为什么C#中的动态类型是静态的?

58

在阅读和探索动态关键字时,我在 《使用类型 dynamic(C#编程指南)》 的 MSDN 页面上找到了以下内容:

该类型是静态类型,但类型为 dynamic 的对象绕过了静态类型检查。在大多数情况下,它的功能类似于类型为 object。

以上句子中静态的含义是什么?它如何绕过静态类型检查?


5
在那个句子中,“static”的意思是你不能真正地在运行时向由dynamic引用引用的任何对象添加东西(成员),就像在动态类型语言(例如JavaScript)中一样。 - Federico Berasategui
2个回答

119

这是静态类型:

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


22
我现在有一种冲动,想根据类所没有的属性和方法来命名它们。 - Tim S.
1
@TimS。现代IDE非常擅长告诉你一个类有什么,但很明显它们没有告诉你它们缺少什么。这就是新的匈牙利标记! - Matt Burland
5
非常好的回答,我感觉我的大脑刚刚又扩展了一点。 - Dunno
2
@DanNeely:不。当你使用“dynamic”时,你会失去智能感知。 - Matt Burland
@Alpha:我不是老VB的专家,但据我所知它有些相似之处。 - Matt Burland
显示剩余4条评论

1

这意味着声明为动态类型的变量将保持动态类型,不能转换为 int 类型的变量。但可以绕过此概念,因为可以更改变量保存的对象的类型。

C#被认为是一种强类型语言,因为变量是静态类型的。这意味着每个变量都有类型,并且 C# 编译器可以检查代码中使用的正确类型。在大多数脚本语言等弱类型语言中,变量的类型是动态的。它们可以保存任何值。


强类型和弱类型是静态语言之间的(有点主观的)区别。例如,我们说 C# 比 C 更强类型,但它们都是静态类型的。你不能真正将强类型或弱类型归因于像 JavaScript 这样的动态语言,因为强/弱的区分首先就意味着一个静态类型系统。 - Theodoros Chatzigiannakis
1
@TheodorosChatzigiannakis:那是错误的。强类型和弱类型以及动态类型和静态类型是正交概念。JS被公认为是动态+弱类型,而Python是动态和强类型。同样,C是静态/弱类型,而C++是静态/强类型。 - mike3996
@progo 好的。直到现在,我绝对不知道在那个上下文中 strong/weak 有任何意义。 - Theodoros Chatzigiannakis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接