2016-09-15 53 views
2

因此,我搜索了其他NullReferenceException和运行时绑定问题,但无法找到此答案。无法在可空类型的空引用上执行运行时绑定

基本上,我有下面的代码。无法执行:ManipulateConcrete返回False,正如你所期望它,但该方法Manipulate抛出

“Microsoft.CSharp.RuntimeBinder.RuntimeBinderException”发生在 System.Core.dll

附加信息的方法运行时对空结合 参考

代码:

class Program 
    { 
     static void Main(string[] args) 
     { 
      var myClassInstance = new MyClass() { MyGuid = null }; 

      ManipulateConcrete(myClassInstance); 
      Manipulate(myClassInstance); 
      Console.ReadLine(); 
     } 

     static void Manipulate(dynamic myClass) 
     { 
      Console.WriteLine(myClass.MyGuid.HasValue); 
     } 

     static void ManipulateConcrete(MyClass myClass) 
     { 
      Console.WriteLine(myClass.MyGuid.HasValue); 
     } 

    } 

    class MyClass 
    { 
     public Guid? MyGuid; 
    } 

我是否错过了一些非常明显的东西?或者这是动态的限制吗?如果是后者,是否有人知道这个的根本原因?

回答

2

使用dynamic时,不考虑静态类型。因此,在Manipulate内,myClass.MyGuid的值为null,输入为dynamic。并且dynamic不知道如何访问null实例上的任何属性,因此会抛出。解决这个问题

一种方法是用null比较,而不是使用.HasValue,:

Console.WriteLine(myClass.MyGuid != null); 

另一种选择是的话,被铸造Guid?摆脱dynamic

Guid? guid = myClass.MyGuid; 

Console.WriteLine(guid.HasValue); 
+0

是啊,我注意到!= null的作品,但在想这里玩的内部机制。在我看来,cli知道这是一个Guid? (尽管它是动态类型的)。是否有一个原因,它不会自动执行演员,然后尝试评估一个名为动态的属性(这可能是另一个问题) – Kolichikov

+0

是什么让你认为它知道它是一个“Guid”?它不是。 'dynamic'基于值的运行时类型,除了这里没有值外,因为''''''''Guid?'被装箱成真正的''''动态''。 – svick

+0

当在动态实例中输入debug和设置Watch时,VS仍然能够确定MyGuid的类型是'System.Guid?',并且我认为这也可以用于CLI(否则,VS得到这些信息?) – Kolichikov

相关问题