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.