dynamic和System.Object之间的区别

声明为dynamic的变量和声明为System.Object的变量之间有什么区别? 运行以下函数似乎表明两个变量都动态地转换为正确的类型:

void ObjectTest() { System.Object MyTestVar = "test"; dynamic MyTestVar2 = "Testing 123"; Console.WriteLine("{0}", MyTestVar.GetType()); Console.WriteLine("{0}", MyTestVar2.GetType()); MyTestVar = 123; MyTestVar2 = 321; Console.WriteLine("{0}", MyTestVar.GetType()); Console.WriteLine("{0}", MyTestVar2.GetType()); } 

区别在于MyTestVar2.ToUpper()编译和工作,没有任何显式转换。

object是普通类型。
dynamic基本上是一个占位符类型,它使编译器发出动态的后期绑定调用。

GetType()是由object类定义的普通函数,该object类在您调用它的实例上运行。
GetType()完全不受引用您调用它的对象的变量的声明类型的影响。 (除了nullables)

您应该从这篇优秀的MSDN文章开始 。 可以非常简洁地总结这些差异:

在编译时,假定键入为动态的元素支持任何操作。

System.Object只有一些它支持的操作 – ToString()Equals()等。

根本区别在于编译时(对象)与运行时(动态)调用的重新组合。 它也被称为早期与晚期绑定。 [注意:添加对Microsoft.CSharp的引用,以便编译以下代码。

  object o = "Hello world";// fine because a derived type can be assigned to a base type dynamic d= "Hello world";// fine as well Type otype=o.GetType();// compiles because it confirms that object has a GetType() Type dtype=d.GetType();// also compiles but for another reason (ieno binding yet) string upperd= d.ToUpper(); // compiles because no binding yet ( anything goes :) string uppero= o.ToUpper(); // Fails to compile. Object has no ToUpper() method 

如果你注释掉最后一个调用,应用程序运行正常,因为CLR,当它在运行时到达第二个最后一次调用d.ToUpper()时,它将在字符串类型中查找方法ToUpper()并在那里找到它(因为在第二个语句中d被分配了一个字符串)。 最后一次调用没有编译,因为在编译时在System.Object类型中搜索ToUpper(),当然不会在那里。