2010-08-12 87 views
7

声明为动态的变量和声明为System.Object的变量之间有什么区别?运行下面的功能似乎表明,这两个变量会马上转换为动态的正确类型:动态和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()); 
} 
+1

前段时间我写了一篇关于这个帖子的文章:http://blogs.msdn.com/b/csharpfaq/archive/2010/01/25/what-is-the-difference-between-dynamic-and-object -keywords.aspx – 2010-08-12 21:15:37

回答

6

不同的是,MyTestVar2.ToUpper()编译和作品,没有任何明确的铸造。

object是正常类型。
dynamic基本上是一个占位符类型,它会导致编译器发出动态的延迟调用。

GetType()object类定义的一个正常函数,它在您调用它的实例上运行。
GetType()完全不受引用您所调用对象的变量的声明类型的影响。 (可空)除外

+0

所以你在说什么,你可以在动态变量上调用特定于对象的方法? – Icemanind 2010-08-12 01:27:25

+2

您可以在'dynamic'变量上调用_any_方法。代码'dynamic x = 3; x.Explode();'会很好的编译 – SLaks 2010-08-12 01:28:52

1

您应该从这个优秀的MSDN article开始。差异可以概括相当简洁:

在编译的时候,也就是 类型为动态假定支持 任何操作的元素。

System.Object只操作了一把,它支持 - ToString()Equals()

1

的根本区别是编译时间(对象)与运行时(动态) resoulution电话。它也被称为早期与晚期绑定。 [注:添加引用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 (i.e.no 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被分配了一个字符串)。最后一次调用没有编译,因为ToUpper()在编译时在System.Object类型中搜索,当然不会在那里。