C# 匿名类型与动态类型

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/391529/
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-04 01:42:37  来源:igfitidea点击:

Anonymous Type vs Dynamic Type

c#.netdynamicanonymous-types

提问by Satish

What are the real differences between anonymous type(var) in c# 3.0 and dynamic type(dynamic) that is coming in c# 4.0?

c# 3.0 中的匿名类型(var)与 c# 4.0 中的动态类型(dynamic)之间的真正区别是什么?

采纳答案by Andrew Hare

An anonymous type is a real, compiler-generated type that is created for you. The good thing about this is that the compiler can re-use this type later for other operations that require it as it is a POCO.

匿名类型是为您创建的真实的、编译器生成的类型。这样做的好处是编译器可以稍后将这种类型重新用于需要它的其他操作,因为它是 POCO。

My understanding of dynamic types is that they are late-bound, meaning that the CLR (or DLR) will evaluate the object at execution time and then use duck typing to allow or disallow member access to the object.

我对动态类型的理解是它们是后期绑定的,这意味着 CLR(或 DLR)将在执行时评估对象,然后使用鸭子类型来允许或禁止成员访问对象。

So I guess the difference is that anonymous types are true POCOs that the compiler can see but you can only use and dynamic types are late-bound dynamic objects.

所以我想区别在于匿名类型是编译器可以看到但您只能使用的真正 POCO,而动态类型是后期绑定的动态对象。

回答by Colby Africa

Check out Ander's presentation here:

在此处查看 Ander 的演示文稿:

http://channel9.msdn.com/pdc2008/TL16/

http://channel9.msdn.com/pdc2008/TL16/

HTM

高铁

回答by Marc Gravell

The dynamictype is essentially object, but will resolve all method / property / operator etc calls at runtimevia the DLR or other provider (such as reflection).

dynamic类型本质上是object,但会在运行时通过 DLR 或其他提供程序(例如反射)解析所有方法/属性/运算符等调用。

This makes it much like VB with Option Strict Off, and makes it very versatile for calling into COM, or into DLR types.

这使它与带有 的 VB 非常相似Option Strict Off,并且在调用 COM 或 DLR 类型时非常通用。

There is notype checking at compile time with dynamic; convesely, anonymous types are proper static-typed, type-checked beasts (you can see them in reflector, although they aren't pretty).

没有类型在编译时动态检查; 简而言之,匿名类型是正确的静态类型、类型检查的野兽(您可以在反射器中看到它们,尽管它们并不漂亮)。

Additionally, anonymous types can be handled exclusively by the compiler; dynamicrequires extensive runtime support - so anonymous types are a C# feature, but dynamicwill largely be implemented by .NET 4.0 (with some C# 4.0 support).

此外,匿名类型可以由编译器专门处理;dynamic需要广泛的运行时支持——所以匿名类型是 C# 的一个特性,但dynamic主要由 .NET 4.0 实现(有一些 C# 4.0 支持)。

回答by Amy B

There's three times, with three actors - one in each time.

有三次,有三个演员——每次一个。

  • Design-time - programmer
  • Compile-time - c# compiler
  • Run-time - .net runtime
  • 设计时 - 程序员
  • 编译时 - c# 编译器
  • 运行时 - .net 运行时

Anonymous types are declared and named by the compiler. This declaration is based on the programmer's specification (how he used the type). Since these types are named after the programmer has left the process, they appear to be nameless to the programmer, hence "anonymous".

匿名类型由编译器声明和命名。此声明基于程序员的规范(他如何使用类型)。由于这些类型是在程序员离开进程后命名的,因此它们对程序员来说似乎是无名的,因此是“匿名的”。

  • The programmer says: Some type has a Name and Address
  • The compiler says : There's a type named xyz with Name and Address properties and fields, both strings.
  • the runtime says : I can't tell any difference between xyz and any type that the programmer made.
  • 程序员说:某些类型有名称和地址
  • 编译器说:有一个名为 xyz 的类型,带有 Name 和 Address 属性和字段,都是字符串。
  • 运行时说:我看不出 xyz 和程序员制作的任何类型之间有什么区别。

dynamic typing in c# allows you to call methods that may or may not exist at compile time. This is useful for calling into python or javascript, which are not compiled.

c# 中的动态类型允许您调用在编译时可能存在也可能不存在的方法。这对于调用未编译的 python 或 javascript 很有用。

  • The programmer says: treat this instance of a car as a dynamic type. Now, quack.
  • The compiler says: dynamic typing eh? must be ok. I won't complain because I can't check it.
  • The runtime attempts to make the instance of car, quack.
  • 程序员说:把这个汽车实例当作动态类型。现在,嘎嘎。
  • 编译器说:动态类型啊?一定没问题。我不会抱怨,因为我无法检查它。
  • 运行时试图创建汽车实例,嘎嘎。

回答by J?rg W Mittag

You seem to be mixing three completely different, orthogonal things:

您似乎混合了三种完全不同的正交事物:

  • static vs. dynamictyping
  • manifest vs. implicittyping
  • named vs. anonymoustypes
  • 静态与动态类型
  • 清单与隐式类型
  • 命名类型与匿名类型

Those three aspects are completely independent, they have nothing whatsoever to do with each other.

这三个方面是完全独立的,彼此之间没有任何关系。

Static vs. dynamictyping refers to whenthe type checking takes place: dynamic typing takes place at runtime, static typing takes place before runtime.

静态与动态类型是指何时进行类型检查:动态类型发生在运行时,静态类型发生在运行时之前

Manifest vs. implicittyping refers to whether the types are manifest in the source codeor not: manifest typing means that the programmerhas to write the types into the source code, implicit typing means that the type systemfigures them out on its own.

清单与隐式类型是指类型是否在源代码中清单:清单类型意味着程序员必须将类型写入源代码,隐式类型意味着类型系统自己计算出来。

Named vs. anonymoustypes refers to, well, whether the types have names or not.

命名与匿名类型是指类型是否有名称。

The dynamickeyword in C# 4.0 means that this variable, parameter, method, field, property ... whatever is dynamically typed, i.e. that its type will be checked at runtime. Everything that is not typed as dynamic is statically typed. Whether a type is static or dynamic not only determines when type checking takes place, but in C# 4.0 it also determines, when method dispatchtakes place. In C#, method dispatch is done before runtime, based on the static type (with the exception of runtime subtype polymorphism of course), whereas on dynamically typed objects in C# 4.0, method dispatch is done at runtime, based on the runtime type.

dynamicC# 4.0 中的关键字意味着这个变量、参数、方法、字段、属性......无论是动态类型的,即它的类型将在运行时检查。不是动态类型的所有内容都是静态类型的。类型是静态的还是动态的不仅决定了何时进行类型检查,而且在 C# 4.0 中它还决定了何时进行方法分派。在 C# 中,方法分派在运行时之前完成,基于静态类型(当然运行时子类型多态除外),而在 C# 4.0 中的动态类型对象上,方法分派在运行时完成,基于运行时类型。

The varkeyword in C# 3.0 means that this local variable will be implicitly typed, i.e. that instead of the programmer writing down the type explicitly, the type system will figure it out on its own. This has nothing to do with dynamic typing, at least in C# 3.0. The variable will be strongly statically typed just as if you had written down the type yourself. It is merely a convenience: for example, why would you have to write down all the type names twicein HashMap<int, string> foo = new HashMap<int, string>();when the type system can clearlyfigure out that foois a HashMap<int, string>, so instead you write var foo = new HashMap<int, string();. Please note that there is nothing dynamic or anonymous about this. The type is static and it has a name: HashMap<int, string>. Of course, in C# 4.0, if the type system figures out that the right hand side of the assignment is dynamic, then the type of the variable on the left hand side will be dynamic.

varC# 3.0 中的关键字意味着这个局部变量将被隐式类型化,也就是说,不是程序员显式写下类型,而是类型系统自己计算出来。这与动态类型无关,至少在 C# 3.0 中是这样。变量将是强静态类型的,就像您自己写下类型一样。它仅仅是一个方便的:比如,为什么你要记下所有的类型名称两次HashMap<int, string> foo = new HashMap<int, string>();当类型系统可以清楚地弄清楚,foo是一个HashMap<int, string>,所以不是你写的var foo = new HashMap<int, string();。请注意,这不是动态的或匿名的。该类型是静态的,它有一个名称:HashMap<int, string>. 当然,在 C# 4.0 中,如果类型系统发现赋值的右侧是动态的,那么左侧变量的类型将是动态的。

An anonymous typein C# 3.0 means that this type has no name. Well, actually, realanonymous types would have required a backwards-incompatible change to the Common Type System, so what actuallyhappens behind the curtain is that the compiler will generate a very long, very random, unique and illegal name for the type and put that name in wherever the anonymous type appears. But from the programmer's point of view, the type has no name. Why is this useful? Well, sometimes you have intermediate results that you only need briefly and then throw away again. Giving such transient types a name of their own would elevate them to a level of importance that they simply don't deserve. But again, there is nothing dynamic about this.

C# 3.0 中的匿名类型意味着该类型没有名称。嗯,实际上,真正的匿名类型需要对通用类型系统进行向后不兼容的更改,因此幕后实际发生的是编译器将为该类型生成一个非常长、非常随机、唯一且非法的名称并放入该名称出现在匿名类型出现的任何地方。但是从程序员的角度来看,类型是没有名字的。为什么这很有用?好吧,有时您会得到中间结果,您只需要简单地使用它们,然后又将其丢弃。给这种瞬态类型一个自己的名字会提升它们的重要性,而它们根本不配。但同样,这没有任何动态。

So, if the type has no name, how can the programmer refer to it? Well, she can't! At least not directly. What the programmer cando, is describe the type: it has two properties, one called "name" of type string, the other called "id" of type int. That's the type I want, but I don't care what it's called.

那么,如果类型没有名称,程序员如何引用它呢?好吧,她不能!至少不是直接的。程序员可以做的是描述类型:它有两个属性,一个叫做 type 的“name” string,另一个叫做type的“id” int。那是我想要的类型,但我不在乎它叫什么。

Here is where the pieces start to come together. In C#, you have to declare the types of local variables by explicitly writing down the names of the types. But, how can you write down the name of a type that has no name? This is where varcomes in: because since C# 3.0, this is actually no longer true: you no longer have to write down the names, you can also tell the compiler to figure it out. So, while what I wrote in the first paragraph above is true, that implicit typing and anonymous types don't have anything to do with other, it is also true that anonymous types would be pretty useless without implicit typing.

这是各个部分开始融合的地方。在 C# 中,您必须通过显式写下类型的名称来声明局部变量的类型。但是,你怎么能写下一个没有名字的类型的名字呢?这就是问题所在var:因为从 C# 3.0 开始,这实际上不再正确:您不再需要写下名称,您还可以告诉编译器来解决它。因此,虽然我在上面第一段中所写的内容是正确的,隐式类型和匿名类型与其他类型没有任何关系,但如果没有隐式类型,匿名类型也将毫无用处。

Note, however, that the opposite is not true: implicit typing is perfectly useful without anonymous types. var foo = HashMap<int, string>makes perfect sense and there's no anonymous type in sight.

但是请注意,相反的情况并非如此:隐式类型在没有匿名类型的情况下非常有用。var foo = HashMap<int, string>完全有道理,而且看不到匿名类型。

回答by goku_da_master

Nothing like a little code to clear things up:

没有什么比一些小代码更能解决问题的了:

// anonymous types
var anonType = new {Id = "123123123", Name = "Goku", Age = 30, DateAdded = new DateTime()};
// notice we have a strongly typed anonymous class we can access the properties with
Console.WriteLine($"Anonymous Type: {anonType.Id} {anonType.Name} {anonType.Age} {anonType.DateAdded}");
// compile time error
//anonType = 100;

// dynamic types
dynamic dynType = 100.01m;
Console.WriteLine($"Dynamic type: {dynType}");
// it's ok to change the type however you want
dynType = new List<DateTime>();
Console.WriteLine($"Dynamic type: {dynType}");

// mix dynamic and anonymous
dynamic dynamicAnonymousType = new {Id = 8000, FirstName = "Goku", Gender = "male", IsSuperSaiyan = true};
// Wasn't sure this would work but it does! However, you lose intellisense on the FirstName so you have to type it manually.
Console.WriteLine($"FirstName: {dynamicAnonymousType.FirstName}");
dynamicAnonymousType = 100;
Console.WriteLine(dynamicAnonymousType);
// runtime error
Console.WriteLine($"Id: {dynamicAnonymousType.FirstName}");