What are the real differences between anonymous type(var) in c# 3.0 and dynamic type(dynamic) that is coming in c# 4.0?
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.
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.
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.
You seem to be mixing three completely different, orthogonal things:
- static vs. dynamic typing
- manifest vs. implicit typing
- named vs. anonymous types
Those three aspects are completely independent, they have nothing whatsoever to do with each other.
Static vs. dynamic typing refers to when the type checking takes place: dynamic typing takes place at runtime, static typing takes place before runtime.
Manifest vs. implicit typing refers to whether the types are manifest in the source code or not: manifest typing means that the programmer has to write the types into the source code, implicit typing means that the type system figures them out on its own.
Named vs. anonymous types refers to, well, whether the types have names or not.
The dynamic
keyword 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 dispatch takes 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.
The var
keyword 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 twice in HashMap<int, string> foo = new HashMap<int, string>();
when the type system can clearly figure out that foo
is 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.
An anonymous type in C# 3.0 means that this type has no name. Well, actually, real anonymous types would have required a backwards-incompatible change to the Common Type System, so what actually happens 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.
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 can do, 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.
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 var
comes 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.
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.
very long, very random, unique and illegal
is a great description for Duval Street in Key West –
Tinney 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.
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.
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.
The dynamic
type is essentially object
, but will resolve all method / property / operator etc calls at runtime via the DLR or other provider (such as reflection).
This makes it much like VB with Option Strict Off
, and makes it very versatile for calling into COM, or into DLR types.
There is no type 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; dynamic
requires extensive runtime support - so anonymous types are a C# feature, but dynamic
will largely be implemented by .NET 4.0 (with some C# 4.0 support).
There's three times, with three actors - one in each time.
- Design-time - programmer
- Compile-time - c# compiler
- Run-time - .net runtime
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.
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.
- 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.
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}");
© 2022 - 2024 — McMap. All rights reserved.