It seems you are mixing three completely different orthogonal things:
- static and dynamic typing
- manifest against implicit typing
- named against anonymous types
These three aspects are completely independent, they have nothing to do with each other.
Static or dynamic typing refers to when type checking occurs: dynamic typing is performed at run time, static typing is performed before execution.
The manifesto against implicit typing refers to whether types are explicit in the source code or not: manifest typing means that the programmer must write the types to the source code, implicit typing means that the type system computes them on its own.
Named or anonymous types refer to whether the types have names or not.
The dynamic keyword in C # 4.0 means that this variable, parameter, method, field, property ... no matter what 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 occurs, but in C # 4.0, it also determines when a method is dispatched. In C #, method dispatch is performed at runtime based on a static type (except for polymorphism of runtime subtypes), while on dynamically typed objects in C # 4.0, method dispatch is performed at runtime based on the type of runtime.
The var keyword in C # 3.0 means that this local variable will be implicitly entered, i.e. that instead of the programmer writing the type explicitly, the type system will decide on its own. This has nothing to do with dynamic typing, at least in C # 3.0. The variable will be strongly statically entered as if you yourself wrote the type. This is just convenience: for example, why do you need to write all type names twice in HashMap<int, string> foo = new HashMap<int, string>(); when the type system can clearly determine that foo is HashMap<int, string> , so instead you write var foo = new HashMap<int, string(); Please note that there is nothing dynamic or anonymous in this. The type is static and has a name: HashMap<int, string> . Of course, in C # 4.0, if the type system determines that the right side of the destination is dynamic, the type of the variable on the left will be dynamic.
An anonymous type in C # 3.0 means that this type has no name. Well, in fact, real anonymous types would require a back-incompatible change in the Common Type System, so what really happens behind the curtain is that the compiler will generate a very long, very random, unique and illegal name for the type and put is the name where the anonymous type appears. But from the point of view of the programmer, the type has no name. Why is this useful? Well, sometimes you have intermediate results that you only need in brief, and then throw them away again. Providing such transitional types alone could raise them to a level of importance that they simply do not deserve. But then again, there is nothing dynamic about it.
So, if a type does not have a name, how can a programmer access it? Well, she can't! At least not directly. What a programmer can do is describe the type: it has two properties, one of which is called a "name" of type string , the other is called "id" of type int . This is the type I want, but I donβt care what he called.
Here the pieces begin to come together. In C #, you must declare types of local variables by explicitly writing type names. But how can you spell a name of a type that has no name? This is where var occurs: since with C # 3.0 this is actually no longer true: you no longer need to write down the names, you can also tell the compiler to figure this out. So, although what I wrote in the first paragraph above is true that implicit typings and anonymous types have nothing to do with others, it is also true that anonymous types would be useless without implicit typing.
Note, however, that the opposite is not true: implicit typing is completely useful without anonymous types. var foo = HashMap<int, string> makes sense and there is no anonymous type in the field of view.