动态 (C# 4) 和 var 之间有什么区别?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/961581/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 04:18:25  来源:igfitidea点击:

What's the difference between dynamic (C# 4) and var?

c#dynamic

提问by Ivan Prodanov

I had read a ton of articles about that new keyword that is shipping with C# v4, but I couldn't make out the difference between a "dynamic" and "var".

我已经阅读了大量关于 C# v4 附带的新关键字的文章,但我无法区分“动态”和“var”之间的区别。

This articlemade me think about it, but I still can't see any difference.

这篇文章让我想了想,但我还是看不出有什么区别。

Is it that you can use "var" only as a local variable, but dynamic as both local and global?

是否只能将“var”用作局部变量,而将动态用作局部变量和全局变量?

Could you show some code without dynamic keyword and then show the same code with dynamic keyword?

你能不能显示一些没有 dynamic 关键字的代码,然后用 dynamic 关键字显示相同的代码?

采纳答案by Marc Gravell

varis static typed - the compiler and runtime knowthe type - they just save you some typing... the following are 100% identical:

var是静态类型的——编译器和运行时知道类型——它们只是为你节省了一些输入......以下是 100% 相同的:

var s = "abc";
Console.WriteLine(s.Length);

and

string s = "abc";
Console.WriteLine(s.Length);

All that happened was that the compilerfigured out that smust be a string (from the initializer). In both cases, it knows (in the IL) that s.Lengthmeans the (instance) string.Lengthproperty.

所发生的一切是编译器发现它s必须是一个字符串(来自初始化程序)。在这两种情况下,它都知道(在 IL 中)这s.Length意味着(实例)string.Length属性。

dynamicis a verydifferent beast; it is most similar to object, but with dynamic dispatch:

dynamic是一种非常不同的野兽;它与 最相似object,但具有动态调度:

dynamic s = "abc";
Console.WriteLine(s.Length);

Here, sis typed as dynamic. It doesn't know about string.Length, because it doesn't know anythingabout sat compile time. For example, the following would compile (but not run) too:

在这里,s输入为 dynamic。它不知道string.Length,因为它不知道任何有关s在编译时。例如,以下内容也可以编译(但不能运行):

dynamic s = "abc";
Console.WriteLine(s.FlibbleBananaSnowball);

At runtime (only), it would checkfor the FlibbleBananaSnowballproperty - fail to find it, and explode in a shower of sparks.

在运行时(只),它会检查FlibbleBananaSnowball属性-无法找到它,并在火花淋浴爆炸。

With dynamic, properties / methods / operators / etc are resolved at runtime, based on the actual object. Very handy for talking to COM (which can have runtime-only properties), the DLR, or other dynamic systems, like javascript.

使用dynamic,属性/方法/运算符/等在运行时根据实际对象进行解析。与 COM(可以具有仅运行时属性)、DLR 或其他动态系统(如javascript.

回答by Hans Van Slooten

Variables declared with varare implicitly but staticallytyped. Variables declared with dynamicare dynamically typed. This capability was added to the CLR in order to support dynamic languages like Ruby and Python.

使用var声明的变量是隐式但静态类型的。用dynamic声明的变量是动态类型的。此功能已添加到 CLR 中,以支持 Ruby 和 Python 等动态语言。

I should add that this means that dynamicdeclarations are resolved at run-time, vardeclarations are resolved at compile-time.

我应该补充一点,这意味着动态声明在运行时解析,var声明在编译时解析。

回答by gimel

varis just a shorthand for a normal type declaration, where you let the compiler guess the correct type.

var只是普通类型声明的简写,您可以在其中让编译器猜测正确的类型。

dynamicis a new (static) type, where all checks are done at runtime, not by the compiler.

dynamic是一种新的(静态)类型,其中所有检查都在运行时完成,而不是由编译器完成。

回答by Richard

The type of a variable declared with var is determined by the compiler, it is a shortcut to specifying the type's name, nothing more.

用 var 声明的变量的类型由编译器决定,它是指定类型名称的快捷方式,仅此而已。

However dynamic is determined at runtime, the compiler has no idea of the actual type, and all method/field/property accesses with that variable will be worked out at runtime.

然而动态是在运行时确定的,编译器不知道实际类型,并且所有对该变量的方法/字段/属性访问都将在运行时计算出来。

回答by Shiva Mamidi

Here is simple example which demonstrates difference between Dynamic (4.0) and Var

这是一个简单的例子,展示了 Dynamic (4.0) 和 Var 之间的区别

dynamic  di = 20;
dynamic ds = "sadlfk";
var vi = 10;
var vsTemp= "sdklf";

Console.WriteLine(di.GetType().ToString());          //Prints System.Int32
Console.WriteLine(ds.GetType().ToString());          //Prints System.String
Console.WriteLine(vi.GetType().ToString());          //Prints System.Int32
Console.WriteLine(vsTemp.GetType().ToString());      //Prints System.String

**ds = 12;**   //ds is treated as string until this stmt now assigning integer.

Console.WriteLine(ds.GetType().ToString());          **//Prints System.Int32**

**vs = 12**; //*Gives compile time error* - Here is the difference between Var and Dynamic. var is compile time bound variable.

Shiva Mamidi

湿婆玛米迪

回答by Kartik M

Do not confuse dynamic and var. Declaring a local variable using var is just a syntactical shortcut that has the compiler infer the specific data type from an expression. The var keyword can be used only for declaring local variables inside a method while the dynamic keyword can be used for local variables, fields, and arguments. You cannot cast an expression to var, but you can cast an expression to dynamic. You must explicitly initialize a variable declared using var while you do not have to initialize a variable declared with dynamic.

不要混淆 dynamic 和 var。使用 var 声明局部变量只是一种语法快捷方式,它让编译器从表达式中推断出特定的数据类型。var 关键字只能用于在方法内部声明局部变量,而 dynamic 关键字可用于局部变量、字段和参数。您不能将表达式转换为 var,但可以将表达式转换为动态。您必须显式初始化使用 var 声明的变量,而不必初始化使用 dynamic 声明的变量。

回答by Matthew Layton

var implies that static type checking (early binding) is applied. dynamic implies that dynamic type checking (late binding) is applied. In terms of the code, condsider the following:

var 意味着应用了静态类型检查(早期绑定)。动态意味着应用动态类型检查(后期绑定)。在代码方面,请考虑以下内容:

class Junk
{
    public void Hello()
    {
        Console.WriteLine("Hello");
    }
}

class Program
{
    static void Main(String[] args)
    {
        var a = new Junk();
        dynamic b = new Junk();

        a.Hello();

        b.Hello();
    }
}

If you compile this and inspect the results with ILSpy, you will find that the compiler has added some late binding code which will handle the call to Hello() from b, whereas becuase early binding was applied to a, a is able to call Hello() directly.

如果你编译这个并用 ILSpy 检查结果,你会发现编译器添加了一些后期绑定代码来处理从 b 对 Hello() 的调用,而由于早期绑定应用于 a,a 能够调用 Hello () 直接地。

e.g. (ILSpy disassembly)

例如(ILSpy 反汇编)

using System;
namespace ConsoleApplication1
{
    internal class Junk
    {
        public void Hello()
        {
            Console.WriteLine("Hello");
        }
    }
}

using Microsoft.CSharp.RuntimeBinder;
using System;
using System.Runtime.CompilerServices;
namespace ConsoleApplication1
{
    internal class Program
    {
        [CompilerGenerated]
        private static class <Main>o__SiteContainer0
        {
            public static CallSite<Action<CallSite, object>> <>p__Site1;
        }
        private static void Main(string[] args)
        {
            Junk a = new Junk();      //NOTE: Compiler converted var to Junk
            object b = new Junk();    //NOTE: Compiler converted dynamic to object
            a.Hello();  //Already Junk so just call the method.

                          //NOTE: Runtime binding (late binding) implementation added by compiler.
            if (Program.<Main>o__SiteContainer0.<>p__Site1 == null)
            {
                Program.<Main>o__SiteContainer0.<>p__Site1 = CallSite<Action<CallSite, object>>.Create(Binder.InvokeMember(CSharpBinderFlags.ResultDiscarded, "Hello", null, typeof(Program), new CSharpArgumentInfo[]
                {
                    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)
                }));
            }
            Program.<Main>o__SiteContainer0.<>p__Site1.Target(Program.<Main>o__SiteContainer0.<>p__Site1, b);
        }
    }
}

The best thing you can do to discover the difference is to write yourself a little console app like this one, and test it yourself with ILSpy.

要发现差异,您可以做的最好的事情就是为自己编写一个像这样的小控制台应用程序,然后自己使用 ILSpy 进行测试。

回答by Suneel Gupta

I am going to explain difference between dynamicand var.

我将解释dynamicvar之间的区别。

dynamic d1;
d1 = 1;
d1 = "http://mycodelogic.com";

This will work. compiler can re-create the type of dynamicvariable.
first it create type as integerand after that compiler will recreate type as string
but in case of var

这将起作用。编译器可以重新创建动态变量的类型。
首先它将类型创建为整数,然后编译器将重新创建类型为字符串,
但在var 的情况下

var v1;  // Compiler will throw error because we have to initialized at the time of declaration  
var v2 = 1; // Compiler will create v1 as **integer**
v2 = "Suneel Gupta"; // Compiler will throw error because, compiler will not recreate the type of variable 



When using the ‘var' keyword, the type is decided by the compiler at compile time, whereas when using the ‘dynamic' keyword, the type is decided by the runtime.
var' keyword, a strongly implicitly typed local variable for which the compiler is able to determine the type from the initialization expression - very useful when doing LINQ programming.
Compiler doesn't have any information about the dynamictype of variable. so compiler will not show any intelligence .
compiler has all information about the stored value of vartype so compiler will show intelligence.
dynamictype can be passed as function argument and function also can return object type
But
vartype can not be passed as function argument and function can not return object type. This type of variable can work in the scope where it defined.
当使用' var'关键字时,类型由编译器在编译时决定,而当使用' dynamic'关键字时,类型由运行时决定。
' var'关键字,一个强隐式类型的局部变量,编译器能够从初始化表达式中确定类型 - 在进行 LINQ 编程时非常有用。
编译器没有关于变量动态类型的任何信息。所以编译器不会显示任何智能。
编译器拥有有关var类型存储值的所有信息,因此编译器将显示智能。
动态类型可以作为函数参数传递,函数也可以返回对象类型
但是
var类型不能作为函数参数传递,函数不能返回对象类型。这种类型的变量可以在它定义的范围内工作。

回答by Abhishek Gahlout

dynamic variable and var variable both can store any type of value but its required to initialize 'var' at the time of declaration.

动态变量和 var 变量都可以存储任何类型的值,但需要在声明时初始化“var”。

Compiler doesn't have any information about the 'dynamic' type of variable. var is compiler safe i.e compiler has all information about the stored value, so that it doesn't cause any issue at run-time.

编译器没有关于“动态”类型变量的任何信息。var 是编译器安全的,即编译器拥有有关存储值的所有信息,因此它不会在运行时引起任何问题。

Dynamic type can be passed as function argument and function also can return it. Var type can not be passed as function argument and function can not return object type. This type of variable can work in the scope where it defined.

动态类型可以作为函数参数传递,函数也可以返回它。var 类型不能作为函数参数传递,函数不能返回对象类型。这种类型的变量可以在它定义的范围内工作。

In case of dynamic Casting is not require but you need to know the property and methods related to stored type , while for var No need to cast because compiler has all information to perform operation.

在动态转换的情况下不需要但您需要知道与存储类型相关的属性和方法,而对于 var 不需要转换,因为编译器拥有执行操作的所有信息。

dynamic: Useful when coding using reflection or dynamic language support or with the COM objects, because we require to write less amount of code.

动态:在使用反射或动态语言支持或使用 COM 对象进行编码时很有用,因为我们需要编写较少的代码。

var: Useful when getting result out of the linq queries. In 3.5 framework it introduce to support linq feature.

var:从 linq 查询中获取结果时很有用。在 3.5 框架中它引入了支持 linq 功能。

Reference : Counsellingbyabhi

参考:咨询byabhi

回答by kuttychutty

  1. The Var(Implicit typed local variable) keyword is used to define local variables.In case of Var , the underlying data type is determined at compile time itself based on the initial assignment.Once the initial assignment has been made with Var type , then it will become strongly typed.If you try to store any incompatible value with the Var type it will result in compile time error.
  1. Var(Implicit typed local variable) 关键字用于定义局部变量。在 Var 的情况下,底层数据类型是在编译时根据初始赋值自行确定的。一旦对 Var type 进行了初始赋值,那么它将成为强类型。如果您尝试存储任何与 Var 类型不兼容的值,它将导致编译时错误。

Example:

例子:

Var strNameList=new List<string>(); By using this statement we can store list of names in the string format. 
strNameList.add("Senthil");
strNameList.add("Vignesh");

strNameList.add(45); // This statement will cause the compile time error.

But in Dynamic type, the underlying type is determined only at run time.Dynamic data type is not checked at compile time and also it is not strongly typed.We can assign any initial value for dynamic type and then it can be reassigned to any new value during its life time.

但在动态类型中,底层类型仅在运行时确定。动态数据类型在编译时不检查,也不是强类型。我们可以为动态类型分配任何初始值,然后可以将其重新分配给任何新的其生命周期内的价值。

Example:

例子:

dynamic test="Senthil";
Console.Writeline(test.GetType())  // System.String

test=1222;
Console.Writeline(test.GetType())  // System.Int32

test=new List<string>();
Console.Writeline(test.GetType())  //System.Collections.Generic.List'1[System.String]

It doesn't provide IntelliSense support also.It doesn't give better support when we give work with linq also.Because it doesn't support lambda expressions ,extension methods and anonymous methods.

它也不提供 IntelliSense 支持。当我们也使用 linq 时,它也没有提供更好的支持。因为它不支持 lambda 表达式、扩展方法和匿名方法。