我第一次使用var
关键字在我身上碰到了一个异常。
采取这种非常简单的方法
public static Int32? GetNullableInt32(Int32 num)
{
return new Nullable<Int32>(num);
}
现在,我们可以使用
dynamic
参数调用此方法,一切都会按预期进行。public static void WorksAsAdvertised()
{
dynamic thisIsAnInt32 = 42;
//Explicitly defined type (no problems)
Int32? shouldBeNullableInt32 = GetNullableInt32(thisIsAnInt32);
Console.Write(shouldBeNullableInt32.HasValue);
}
但是,通过使用隐式类型声明
shouldBeNullableInt32
,结果与我的预期相去甚远。public static void BlowsUpAtRuntime()
{
dynamic thisIsAnInt32 = 42;
//Now I'm a dynamic{int}... WTF!!!
var shouldBeNullableInt32 = GetNullableInt32(thisIsAnInt32);
//Throws a RuntimeBinderException
Console.Write(shouldBeNullableInt32.HasValue);
}
返回值不是
Nullable<Int32>
,而是被视为动态类型。即使这样,底层的Nullable<T>
也不会保留。由于System.Int32
没有名为HasValue
的属性,因此会抛出RuntimeBinderException
。我很想知道谁会真正解释正在发生的事情(而不仅仅是猜测),所以很奇怪。
两个问题
shouldBeNullableInt32
的返回类型明确返回GetNullableInt32
时,为什么Nullable<Int32>
隐式地将键入作为动态? Nullable<Int32>
不保留?为什么改为dynamic{int}
? (在这里回答:C# 4: Dynamic and Nullable<>)更新
Rick Sladkey's answer和Eric Lippert's answer均有效。请同时阅读它们:)
最佳答案
这是因为虽然对我们来说GetNullableInt32
是要被调用的方法,但是由于dynamic binding,确实被调用的实际方法被推迟到运行时,因为它是用动态参数调用的。 GetNullableInt32
可能还有另一个重载,它与thisIsAnInt32
的运行时值更好地匹配。直到运行时才知道的另一种方法可能返回Int32?
以外的其他类型!
结果,由于动态绑定(bind)而不是静态绑定(bind),因此编译器无法假定表达式在编译时的返回类型是什么,因此表达式返回的类型为 dynamic 。将鼠标悬停在var
上可以看到这一点。
您似乎已经对这里的第二个问题获得了令人满意的解释:
关于c# - 使用 'var'和 'dynamic'时出现异常,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7439637/