新的“dynamic”关键字是否取代了“var”关键字?

27

当C# 4.0推出并且我们有动态关键字,就像Anders Hejlsberg在这个极好的演示中所描述的那样,(C# 的发展速度比我跟得上的要快...我没有太多时间熟悉 var 关键字)

那我还需要 var 关键字吗?有什么 var 能做到而 dynamic 不能做到的吗?

var x = SomeFunctionThatIKnowReturnsSomeKindOfList();
// do something with x

dynamic x = SomeFunctionThatIKnowReturnsSomeKindOfList();
// do something with x

3
或许不是很重要,但是var是一个关键字,而dynamic则不是。它是一种数据类型。 - TimothyP
所以它的“动态”基本上就像声明一个类型为“object”的东西,但是编译器不会抱怨,当你调用不存在的方法时? - user65199
1
是的,它将在运行时解决。如果存在,该方法将被调用... 如果不存在,则会出错! - Gishu
3个回答

72

不,它们非常不同。

var 的意思是“在编译时推断变量的类型” - 但它仍然完全是静态绑定的。

dynamic 的意思是“假设我可以对这个变量进行任何操作” - 也就是编译器不知道哪些操作是可用的,DLR 会在执行时确定调用的真正含义。

我预计很少使用 dynamic - 只有当我真正需要动态行为时才会使用:

  • var 允许您在编译时捕捉拼写错误等问题
  • 静态绑定代码始终比动态绑定代码运行得更快(即使差异变得相当小)
  • 静态绑定代码提供了更多的编译时支持,不仅仅是错误:您可以找到调用层次结构,重构将工作得更好,Intellisense 等都可以使用。

那就是我缺失的部分... var 是静态绑定(因此具有编译时检查、工具等优点)。 - Gishu
1
你可以把var基本上看作是一些语法糖。 - Boris Callens

17

动态类型和var代表两种完全不同的概念。

var

Var本质上是要求编译器根据赋值语句右侧的表达式来确定变量的类型。然后,该变量被视为显式声明为表达式类型的变量。例如,以下两个语句是等价的:

var a = "foo";
string a = "foo";

这里需要记住的关键是,"var"是100%类型安全的,并且是编译时操作。

动态

动态在很多方面与var完全相反。使用动态实质上是消除了该特定变量的所有类型安全性。它在许多方面没有类型。当您在变量上调用方法或字段时,决定如何调用该字段发生在运行时。例如

dynamic d = SomeOperation();
d.Foo(); // Will this fail or not?  Won't know until you run the program

这里需要记住的关键是,“动态”不安全且是运行时操作。

2
它仍然是类型安全的,只是在编译时不知道类型。如果实际(运行时)对象没有您尝试访问的特定成员,则会引发异常。 - Isak Savo
比较:你可以在.NET 2.0项目中使用var,但不能使用dynamic。 - Vincent Vancalbergh

1

是的,你仍然需要 var:

Var 是一个变量,其类型将由编译器推断。
dynamic 将在运行时分配其类型。

所以:

Var i = "Hello World"

这样做将推断其类型为字符串类型,智能感知将为您提供字符串可以使用的所有方法,例如:

i.Split("/")

其中:

dynamic i = "Hello World"

在运行时之前,由于编译器还不知道它的类型,因此其类型无法推断,但仍然可以执行以下操作:

i.Split("/")

但是当调用你所需要的方法时,可能会因为类型错误或方法不存在而失败。


Pedant: "var" 是一个 变量,其类型将由编译器推断。对象不受影响。"dynamic" 是一个静态类型为 "dynamic" 的变量 - 它是分派机制发生变化的地方(变量仍然被视为 "dynamic" 类型)。 - Marc Gravell

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