我第一次使用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 answerEric Lippert's answer均有效。请同时阅读它们:)

    最佳答案



    这是因为虽然对我们来说GetNullableInt32是要被调用的方法,但是由于dynamic binding,确实被调用的实际方法被推迟到运行时,因为它是用动态参数调用的。 GetNullableInt32可能还有另一个重载,它与thisIsAnInt32的运行时值更好地匹配。直到运行时才知道的另一种方法可能返回Int32?以外的其他类型!

    结果,由于动态绑定(bind)而不是静态绑定(bind),因此编译器无法假定表达式在编译时的返回类型是什么,因此表达式返回的类型为 dynamic 。将鼠标悬停在var上可以看到这一点。

    您似乎已经对这里的第二个问题获得了令人满意的解释:

  • C# 4: Dynamic and Nullable<>
  • 关于c# - 使用 'var'和 'dynamic'时出现异常,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7439637/

    10-13 04:20