这是静态类型:
string foo = "bar";
foo 现在是一个字符串,所以这会导致编译时错误:
foo = 1;
即使你使用var,它仍然是静态类型的:
var foo = "bar"; // foo is now a string
foo = 1; // still a compile time error
使用动态关键字,意味着类型不会是静态的,可以改变,所以现在你可以这样做:
dynamic foo = "bar";
foo = 1; // this is now fine.
现在,为什么说“该类型是静态类型”是因为在许多动态语言(如 Javascript)中,您可以执行以下操作:
var foo = { bar: 1 };
这会创建一个具有名为“bar”的属性的对象,然后您可以这样做:
foo.la = 2;
向foo 中的对象添加一个新属性。但是如果你在 C# 中尝试同样的技巧
dynamic foo = new SomeClassThatDoesntHaveABarProperty();
foo.bar = 2; // runtime error
您也不能删除属性。您可以将任何类型分配给动态变量,但您不能自行更改这些类型。
如果您确实需要这种类型的功能,那么您需要查看ExpandoObject
正如您的描述所说,dynamic 在很多情况下的功能类似于对象。你可以这样做:
dynamic foo = new Foo();
foo = new Bar();
就像这样:
object foo = new Foo();
foo = new Bar();
但是当你想使用属性或方法时,区别就出现了。有了动态,我可以这样做:
dynamic foo = new Foo();
foo.FooMethod(); // Note: You WILL get a runtime exception if foo doesn't have a FooMethod
但是对于一个对象,我需要这样做:
object foo = new Foo();
((Foo)foo).FooMethod(); // Note: I HAVE to know the type at compile time here
只有在我已经知道我可以将 foo 中的类型转换为 Foo 类型的情况下才能做到这一点在编译时,如果我已经知道,那么我可以使用Foo 作为我的类型,而不是object。