【问题标题】:Why is C# dynamic type static?为什么 C# 动态类型是静态的?
【发布时间】:2014-09-27 06:43:14
【问题描述】:

在阅读和探索动态关键字时,我在 [MSDN](Using Type dynamic (C# Programming Guide))上找到了以下行:

该类型是静态类型,但动态类型的对象绕过静态类型检查。在大多数情况下,它的功能就像它具有类型对象一样。

上面一行中的static是什么意思,它是如何绕过静态类型检查的?

【问题讨论】:

  • 那句话中“静态”的含义是,你不能在运行时真正“添加”东西(成员)到dynamic引用所引用的任何对象(就像你可以动态地例如 javascript 等类型语言)。

标签: c# c#-4.0 dynamic


【解决方案1】:

这是静态类型:

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

【讨论】:

  • 我现在想根据类没有具有的属性和方法来命名我的类。
  • @TimS。现代 IDE 非常擅长准确地告诉您一个类 有什么,显然他们没有告诉你他们没有 有什么。这是新的匈牙利符号!
  • 很好的答案,我感觉我的大脑刚刚膨胀了一点。
  • 在这种dynamic foo = new Foo(); foo.FooMethod(); 的情况下,Intelisense 是否能够弄清楚foo 是什么类型以便为您完成FooMethod()
  • @DanNeely:不。当你使用dynamic时你会失去智能。
【解决方案2】:

这意味着声明为动态的变量将保持动态类型,并且不能更改为例如 int 类型的变量。但是这个概念被绕过了,因为你可以改变变量所持有的对象的类型。

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

【讨论】:

  • 强/弱类型是静态类型语言之间的(有点主观的)区别。例如,我们说 C# 的类型比 C 强,但它们都是静态类型的。您不能真正将强类型或弱类型归因于 JavaScript 等动态语言,因为强/弱区别首先意味着静态类型系统。
  • @TheodorosChatzigiannakis:这是错误的。强/弱类型和动态/静态类型是正交的概念。 JS 被公认为动态+弱类型,而 Python 是动态和强类型。同样,C 是静态/弱的,C++ 是静态/强的。
  • @progo 好的。在这种情况下,我绝对不知道强/弱的任何含义,直到现在。
猜你喜欢
  • 2010-10-25
  • 1970-01-01
  • 1970-01-01
  • 2023-03-28
  • 2011-07-03
  • 1970-01-01
  • 2011-11-15
  • 2010-10-16
  • 2012-06-29
相关资源
最近更新 更多