c# - 为什么我不能将 Debug.Assert() 与接受动态并返回 bool 的方法一起使用?

标签 c# .net dynamic conditional-attribute

<分区>

这是我的代码:

class Program
{
    static void Main(string[] args)
    {
        dynamic param = null;
        System.Diagnostics.Debug.Assert(whatever(param));
    }

    static bool whatever(object param)
    {
        return true;
    }
}

当我运行它时,我得到带有以下消息的 RuntimeBinderException:

Cannot dynamically invoke method 'Assert' because it has a Conditional attribute

是的,Assert() 上有 ConditionalAttribute。然而,只有一个 whatever() 方法会返回 bool,无论该方法接受什么。

运行时到底提示什么?为什么它不能使用 bool 并将其传递给 Assert()

最佳答案

Main 中的实际调用被转换为 CallSite,因为您正在使用 动态参数 调用调用。 CallSite 完成所有需要的准备工作,以便在运行时 调用此方法。但是,问题是 Assert 有一个 Conditional 属性,这意味着它需要在编译时<将信息传递给编译器预处理器/强>

blog post explains :

Conditional attributes can be placed on methods (and attributes in whidbey) to instruct the compiler to conditionally remove calls to the function if a symbol is not defined. This can be useful for debug-only functionality, like Debug.Assert, which has a Conditional("DEBUG") on it.

Conditional takes a string argument. If that string is defined (as determined by the compiler's preprocessor), then the compiler emits the method call. If the symbol is not defined, C# still compiles the method, but does not compile the calls.

然后,为了加强我们的观点:

The Conditional attribute is entirely handled by the compiler without any cooperation from the runtime. The method is still jitted normally, but the compiler just doesn't emit the calls if the symbol is not defined.

现在,我们发生了冲突。我们不能在运行时将参数传递给编译器预处理器(告诉它是否定义了“DEBUG”),只能在编译时传递,但该方法只会在运行时调用,因为那是当我们推断出我们的 dynamic 值的类型时。

这就是为什么 Binder 在运行时大喊这个方法实际上不能被调用,因为那样会破坏 ConditionalAttribute

奖励:

这就是实际调用的内容:

private static void Main(string[] args)
{
    object param = null;
    if (Program.<Main>o__SiteContainer0.<>p__Site1 == null)
    {
        Program.<Main>o__SiteContainer0.<>p__Site1 = CallSite<Action<CallSite, Type, object>>.Create(Binder.InvokeMember(CSharpBinderFlags.ResultDiscarded, "Assert", null, typeof(Program), new CSharpArgumentInfo[]
        {
            CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType | CSharpArgumentInfoFlags.IsStaticType, null),
            CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)
        }));
    }
    Action<CallSite, Type, object> arg_CB_0 = Program.<Main>o__SiteContainer0.<>p__Site1.Target;
    CallSite arg_CB_1 = Program.<Main>o__SiteContainer0.<>p__Site1;
    Type arg_CB_2 = typeof(Debug);
    if (Program.<Main>o__SiteContainer0.<>p__Site2 == null)
    {
        Program.<Main>o__SiteContainer0.<>p__Site2 = CallSite<Func<CallSite, Type, object, object>>.Create(Binder.InvokeMember(CSharpBinderFlags.None, "whatever", null, typeof(Program), new CSharpArgumentInfo[]
        {
            CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType | CSharpArgumentInfoFlags.IsStaticType, null),
            CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)
        }));
    }
    arg_CB_0(arg_CB_1, arg_CB_2, Program.<Main>o__SiteContainer0.<>p__Site2.Target(Program.<Main>o__SiteContainer0.<>p__Site2, typeof(Program), param));

关于c# - 为什么我不能将 Debug.Assert() 与接受动态并返回 bool 的方法一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28562834/

相关文章:

c# - 为什么 MSFT C# 编译固定 "array to pointer decay"和 "address of first element"的方式不同?

c# - 接口(interface)的隐式和显式实现

php - 将数据库数据加载为动态页面

javascript - 需要具有动态CSS样式

c# - 如何在 C# 中测试 COM 依赖对象

c# - 为什么 SortedSet<T>.GetViewBetween 不是 O(log N)?

C# bit shift : is this behavior in the spec, 是一个错误,还是偶然的?

c# - 从 Web Api Controller 中的 Post 方法获取任何参数

.net - 处理多个登录系统(Facebook Connect、Google 帐户等)

c# - 如何创建 Expression<Func<dynamic, dynamic>> - 或者它是一个错误?