使用Convert.ToInt64键入推断失败

时间:2015-08-18 03:51:20

标签: c#

以下代码段

static class Program
{
  public static void Main()
  {
     dynamic data = "0001010";
     var value = System.Convert.ToInt64(data);
     System.Console.Out.WriteLine(value.DoubleIt());
  }

  static long DoubleIt(this long source)
  {
      return source * 2;
  }
}

失败
Unhandled Exception: Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 'long' does not contain a definition for 'DoubleIt'
   at CallSite.Target(Closure , CallSite , Object )
   at System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,TRet](CallSite site, T0 arg0)
   at Program.Main()

虽然改变了一点

long value = System.Convert.ToInt64(data);

string data = "0001010";

足以使这项工作。

看看IL,看来前者试图通过反射加载DoubleIt,而后者则导致DoubleIt静态绑定。

为什么会出现这种情况?

1 个答案:

答案 0 :(得分:2)

因为value实际上是dynamic。在编译时,我们实际不知道正在调用哪个System.Convert.ToInt64方法 - 它可能是任何重载(如果有的话)。

因此,您需要明确说valuelong。这告诉编译器你知道你在做什么,如果你不知道你会得到一个运行时错误(例如,如果ToInt64返回了string)。或者,您可以删除动态调用(通过将dynamic替换为string来执行此操作) - 此时我们知道完全正在调用哪个ToInt64方法

当您编写DoubleIt()时 - 您实际上并未绑定到扩展方法。 dynamic并不关心你写的是什么,并会尝试在运行时将其解析为对象本身的一种方法 - 并且不考虑扩展方法

扩展方法只是语法糖,并在IL中编译为:

SomeStaticClass.DoubleIt(value) 这使得为什么无法运行value.DoubleIt()

更加清晰