Jos*_*osh 28 c# compiler-construction dynamic
我在Anomaly上碰到了一点,这是第一次使用var关键字bit me.
采用这种非常简单的方法
public static Int32? GetNullableInt32(Int32 num)
{
return new Nullable<Int32>(num);
}
Run Code Online (Sandbox Code Playgroud)
现在我们可以使用dynamic参数调用此方法,一切都将按预期工作.
public static void WorksAsAdvertised()
{
dynamic thisIsAnInt32 = 42;
//Explicitly defined type (no problems)
Int32? shouldBeNullableInt32 = GetNullableInt32(thisIsAnInt32);
Console.Write(shouldBeNullableInt32.HasValue);
}
Run Code Online (Sandbox Code Playgroud)
但是,通过声明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);
}
Run Code Online (Sandbox Code Playgroud)
而不是Nullable<Int32>返回值get被视为动态类型.即便如此,底层Nullable<T>也不会被保留.由于System.Int32没有命名的属性HasValue,RuntimeBinderException因此抛出了a .
我会非常好奇地听到能够解释正在发生的事情的人(不仅仅是猜测).
shouldBeNullableInt32得到隐式类型为动态时的返回类型GetNullableInt32显然返回Nullable<Int32>?Nullable<Int32>没有保留?为什么dynamic{int}反而?(这里回答:C#4:Dynamic和Nullable <>)无论里克Sladkey的回答和埃里克利珀的回答同样有效.请阅读他们:)
Ric*_*key 20
- 为什么
shouldBeNullableInt32得到隐式类型为动态时的返回类型GetNullableInt32显然返回Nullable<Int32>?
这是因为虽然我们很明显GetNullableInt32这是将要调用的方法,但由于动态绑定,实际调用的方法会延迟到运行时,因为它是使用动态参数调用的.可能有另一个重载匹配更好的运行时值.这种替代方法,直到运行时才能知道,可能会返回一些其他类型的方法!GetNullableInt32thisIsAnInt32Int32?
因此,由于动态绑定而不是静态绑定,编译器无法在编译时假设表达式的返回类型,因此表达式返回类型dynamic.这可以通过悬停看到var.
你似乎已经对你的第二个问题得到了令人满意的解释:
Eri*_*ert 18
Rick的答案很好,但总而言之,您正在遇到该功能的两个基本设计原则的后果:
您确定的第一个问题是第一个设计原则的结果.您要求分析要延迟到运行时的调用.编译器这样做了.这包括将有关调用的所有内容推迟到运行时,包括重载解析和确定返回类型.编译器有足够的信息来猜测你的意思是无关紧要的.
如果编译器确实猜到了你的意思,那么现在你会问一个不同的问题,即"我对可用的方法集进行了微小的改动,然后编译器突然改变了对类型的推论动态,为什么?" 当编译器的行为不可预测时,用户会非常困惑.
(尽管如此,编译器会告诉您动态代码错误的情况很少.在某些情况下我们知道动态绑定在运行时总会失败,我们可以在编译时告诉您它们时间而不是等待你的测试用例失败.)
您确定的第二个问题是第二个设计原则的结果.因为动态只是戴着滑稽帽子的对象,并且因为nullables框为空引用或盒装非可空值类型,所以没有"动态可空"这样的东西.