The Mono documentation has a code example about full AOT not supporting generic interface instantiation:
interface IFoo<T> {
...
void SomeMethod();
}
It says:
Since Mono has no way of determining from the static analysis what method will implement the interface IFoo<int>.SomeMethod this particular pattern is not supported."
So I think the compiler can't work with this method under type inference. But I still can't understand the underlying reason about the full AOT limitation.
There is still a similar problem with the Unity AOT script restrictions. In the following code:
using UnityEngine;
using System;
public class AOTProblemExample : MonoBehaviour, IReceiver
{
public enum AnyEnum {
Zero,
One,
}
void Start() {
// Subtle trigger: The type of manager *must* be
// IManager, not Manager, to trigger the AOT problem.
IManager manager = new Manager();
manager.SendMessage(this, AnyEnum.Zero);
}
public void OnMessage<T>(T value) {
Debug.LogFormat("Message value: {0}", value);
}
}
public class Manager : IManager {
public void SendMessage<T>(IReceiver target, T value) {
target.OnMessage(value);
}
}
public interface IReceiver {
void OnMessage<T>(T value);
}
public interface IManager {
void SendMessage<T>(IReceiver target, T value);
}
I am confused by this:
The AOT compiler does not realize that it should generate code for the generic method OnMessage with a T of AnyEnum, so it blissfully continues, skipping this method. When that method is called, and the runtime can’t find the proper code to execute, it gives up with this error message.
Why does the AOT not know the type when the JIT can infer the type? Can anyone offer a detailed answer?
Before describing the issues, consider this excerpt from another answer of mine that describes the generics situation on platforms that do support dynamic code generation:
In C# generics, the generic type definition is maintained in memory at runtime. Whenever a new concrete type is required, the runtime environment combines the generic type definition and the type arguments and creates the new type (reification). So we get a new type for each combination of the type arguments, at runtime.
The phrase at runtime is key to this, because it brings us to another point:
This implementation technique depends heavily on runtime support and JIT-compilation (which is why you often hear that C# generics have some limitations on platforms like iOS, where dynamic code generation is restricted).
So is it possible for a full AOT compiler to do that as well? It most certainly is possible. But is it easy?
There is a paper from Microsoft Research on pre-compiling .NET generics that describes the interaction of generics with AOT compilation, highlights some potential problems and proposes solutions. In this answer, I will use that paper to try to demonstrate why .NET generics aren't widely pre-compiled (yet).
Everything must be instantiated
Consider your example :
IManager manager = new Manager();
manager.SendMessage(this, AnyEnum.Zero);
Clearly we're calling the method IManager.SendMessage<AnyEnum> here, so the fully AOT compiler needs to compile that method.
But this is an interface call, which is effectively a virtual call, which means the we can't know ahead of time which implementation of the interface method will be called.
The JIT compiler doesn't care about this problem. When someone attempts to run a method that hasn't been compiled yet, the JIT will be notified and it will compile the method lazily.
On the contrary, a fully AOT compiler doesn't have access to all this runtime type information. So it has to pessimistically compile all possible instantiations of the generic method on all implementations of the interface. (Or just give up and not offer that feature.)
Generics can be infinitely recursive
object M<T>(long n)
{
if (n == 1)
{
return new T[]();
}
else
{
return M<T[]>(n - 1);
}
}
To instantiate M<int>(), the compiler needs to instantiate int[] and M<int[]>(). To instantiate M<int[]>(), the compiler needs to instantiate int[][] and M<int[][]>(). To instantiate M<int[][]>(), the compiler needs to instantiate int[][][] and M<int[][][]>().
This can be solved by using representative instantiations (just like the JIT compiler uses). This means that all generic arguments that are reference types can share their code. So:
int[][], int[][][], int[][][][] (and so on) can all share the same code, because they are arrays of references.
M<int[]>, M<int[][]>, M<int[][][]> (and so on) can all share the same code, because they operate on references.
Assemblies need to own their generics...
Since C# programs are compiled in assemblies, it's hard to tell exactly who should "own" which instantiation of each type.
Assembly1 declares the type G<T>.
Assembly2 (references Assembly1) instantiates the type G<int>.
Assembly3 (references Assembly1) instantiates the type G<int> as well.
AssemblyX (references all the above) wants to use G<int>.
Which assembly gets to compile the actual G<int>? If they happen to be standalone libraries, neither Assembly2 nor Assembly3 can be compiled without each owning a copy of G<int>. So we're already looking at duplicated native code.
...and those generics must still be compatible with each other
But then, when AssemblyX is compiled, which copy of G<int> should it use? Clearly, it has to be able to handle both, because it may need to receive a G<int> from or send a G<int> to either assembly.
But more importantly, in C# you can't have two types with identical fully qualified names that turn out to be incompatible. In other words:
G<int> obj = new G<int>();
The above can never fail on the grounds that G<int> (the variable's type) is the G<int> from Assembly2 while G<int> (the constructor's type) is the G<int> from Assembly3. If it fails for a reason like that, we're not in C# anymore!
So both types need to exist and they need to be made transparently compatible, even though they are compiled separately. For this to happen, the type handles need to be manipulated at link time in such a way that the semantics of the language are retained, including the fact that they should be assignable to each other, their type handles should compare as equal (e.g. when using typeof), and so on.
Unity is using an old version of Mono's Full-AOT the does not support generic interface method.
This is due to how generics are represented in the JIT vs in native code. (I would like to elaborate, but frankly, I do not trust myself to be accurate)
Newer versions of Mono's AOT compiler address this issue (of course, with other limitations), but Unity keeps an old version of Mono. (I think I remember hearing that they changed their approach from AOT to something a bit else, but I'm not sure how it works anymore).
I don't fully understand the topic WARNING
The way "generics" are handled in C++ (for example), which compiles to assembly, binary, is using a language mechanism called templates. These templates are more like glorified macros, and different code is actually generated for each type used. (Edit: Actually there are more differences between C# generics and C++ templates, but for the purpose of this answer I'll treat them as equivalent).
For example; for the following code:
template<typename T>
class Foo
{
public:
T GetValue() { return value; }
void SetValue(T a) {value = a;}
private:
T value;
};
int main()
{
Foo<int> a;
Foo<char *> b;
a.SetValue(0);
b.SetValue((char*)0);
a.GetValue();
b.GetValue();
return 0;
}
The following functions will be generated (got this by running nm --demangle)
00000000004005e4 W Foo<int>::GetValue()
00000000004005b2 W Foo<int>::SetValue(int)
00000000004005f4 W Foo<char*>::GetValue()
00000000004005ca W Foo<char*>::SetValue(char*)
This means that for every type you use this class with, another of instance of practically the same code will be generated (although I'm sure that GCC is smart enough to optimize some of the obvious cases, like getters and setters, and maybe more).
C#'s generics are a bit more complex.
Here's a very interesting article by Eric Lippert. The summary is that compiled C# generic code has only one instance that is, well, generic, and what that depends on the type is calculated at runtime.
When translating C# code to native/machine code (which is essentially what AOT does), there's a problem translating generics.
This is where the subject gets a bit fuzzy to me. I can only assume that AOT'd code does not retain runtime type information, so it needs code-per-type for generic cases.
When receiving an object of type IFooable, it is possible that the native virtual table format is not verbose enough to enable finding the correct implementation; although I admit I have no idea why would that be, or the exact details of the virtual table of AOT'd code (is it identical to that of C++'s?)
Related
Say I have two methods, one calls the other. The second method has code that will generate a compile time error. Since it's not called, why does the compiler still bother to process it?
void method1()
{
var i = 1;
//method2();
}
void method2()
{
int i = "2";
}
You can't be sure that someone else won't call that method at runtime using reflection. Your code MUST compile or it's not valid code - if it's never used... comment it out!
To expand on this:
Basically at compile time you are strongly typed - .NET will type check everything to ensure that what you are trying to do is legal, however, you can still throw exceptions at run time due to null references, bad casts etc etc.
Reflection is a component of the .NET framework that allows a developer to inspect the properties/fields/methods etc of an assemblies types via the assembly metadata
Reflection allows runtime type discovery and inspection of these types, it also allows invocation of methods/properties and modification of fields etc. (You can even create new generic types at runtime or completely new types altogether).
In other words, you can't guarantee that code you think won't be called, isn't called somewhere else at some point. For reflection to be possible, every bit of code needs to be valid and compilable
Whether that code will succeed at runtime is another story - but that's why we have exception handling.
And then what if somebody else uses your compiled code later on and decides to use it?
Even with private methods Reflection can complicate matters.
If you don't use it, lose it. (or at least comment it out)
class Poly
{
public static void WriteVal(int i) { System.Console.Write("{0}\n", i); }
public static void WriteVal(string s) { System.Console.Write("{0}\n", s); }
}
class GenWriter<T>
{
public static void Write(T x) { Poly.WriteVal(x); }
}
Why the innocent (for C++ programmer) method Write is not acceptable in C#?
You can see that the compiler tries to match the parameter type T to concrete overloads before instantiation:
Error 3 The best overloaded method match for 'TestGenericPolyMorph.Poly.WriteVal(int)' has some invalid arguments
Of course. the purpose was not to use the static method as above, the intention is to create a wrapper with polymorphic behavior.
Note: I use VS 2010.
Please, note that all the needed information is available in compile time. Once again: the problem is that the validation is performed before the template instantiation.
Addition after the discussion:
Well, may be I have not stressed this out properly.
The question was not only about the difference between generics and templates, but also about solution of the following problem: given set of overloads addressing different types, I want to generate set of wrapper classes providing virtual method (polymorphism) for these types.
The price of resolution of virtual methods in run-time is minimal and does not hit performance. This is where C++ templates were handy. Obviously, the overhead of the run-time type resolution for dynamic is quite different.
So, the question is whether one can convert existing overloads to polymorphism without replication of the code and without paying the performance penalty (e.g., I am not sure what I gain with dynamic compared to "switch" attempting to cast except of nicer syntax).
One of the solutions I have seen so far was to generate/emit code (sic!), i.e. instead of cut-and-paste to do this automatically.
So, instead of the C++ template processing we simply do it manually or just re-invent macro/template processor.
Anything better?
Short answer:
C# generics are not C++ templates; despite their similar syntax they are quite different. Templates are built at compile time, once per instantiation, and the templatized code must be correct for only the template arguments actually provided. Templates do tasks like overload resolution and type analysis once per instantiation; they are basically a smart "search and replace" mechanism on source code text.
C# generics are truly generic types; they must be correct for any possible type argument. The generic code is analyzed once, overload resolution is done once, and so on.
Long answer: This is a duplicate of
What are the differences between Generics in C# and Java... and Templates in C++?
See the long answers there for details.
See also my article on the subject:
http://blogs.msdn.com/b/ericlippert/archive/2009/07/30/generics-are-not-templates.aspx
Why can't you simply write:
public static void Write<T>(T x) { System.Console.Write("{0}\n", x); }
The C++ and C# generics are different ( http://msdn.microsoft.com/en-us/library/c6cyy67b(v=VS.80).aspx , search for "c# c++ generics difference" on your favorite search site)
Short: C# compiler must create complete GenWriter<T> class with all type matching by just looking at the class itself. So it does not know if T will only be int/string or any other type.
C++ compiler creates actual class by looking at instantiation of the generic GenWriter<int> and declaration GenWriter<T> and then creates class for that particular instance.
If someone was to call GenWriter(5.0), this would be inferred to GenWriter<double>(5.0), and the method call inside Write(T x) would become:
public static void Write(double x) { Poly.WriteVal(x); }
There is no overload of WriteVal which takes a double. The compiler is informing you that there are no valid overloads of WriteVal.
C# generics and C++ templates are not entirely equivalent.
You can't do that in C# because the compiler doesn't know what is the type of x in compile time.
Without knowledge of T's actual type, the compiler is concerned that you might have intended to perform a custom conversion. The simplest solution is to use the as operator, which is unamibigous because it cannot perform a custom conversion.
A more gereral solution is to cast to object first. This is helpfull because of boxing unboxing issues:
return (int)(object) x;
Have in mind that C# Generics are not like C++ templates. C++ templates are pieces of code that compile for each type separately. While C# generics are compiled in an assebmly.
I'm interesting in how CLR implementes the calls like this:
abstract class A {
public abstract void Foo<T, U, V>();
}
A a = ...
a.Foo<int, string, decimal>(); // <=== ?
Is this call cause an some kind of hash map lookup by type parameters tokens as the keys and compiled generic method specialization (one for all reference types and the different code for all the value types) as the values?
I didn't find much exact information about this, so much of this answer is based on the excellent paper on .Net generics from 2001 (even before .Net 1.0 came out!), one short note in a follow-up paper and what I gathered from SSCLI v. 2.0 source code (even though I wasn't able to find the exact code for calling virtual generic methods).
Let's start simple: how is a non-generic non-virtual method called? By directly calling the method code, so the compiled code contains direct address. The compiler gets the method address from the method table (see next paragraph). Can it be that simple? Well, almost. The fact that methods are JITed makes it a little more complicated: what is actually called is either code that compiles the method and only then executes it, if it wasn't compiled yet; or it's one instruction that directly calls the compiled code, if it already exists. I'm going to ignore this detail further on.
Now, how is a non-generic virtual method called? Similar to polymorphism in languages like C++, there is a method table accessible from the this pointer (reference). Each derived class has its own method table and its methods there. So, to call a virtual method, get the reference to this (passed in as a parameter), from there, get the reference to the method table, look at the correct entry in it (the entry number is constant for specific function) and call the code the entry points to. Calling methods through interfaces is slightly more complicated, but not interesting for us now.
Now we need to know about code sharing. Code can be shared between two “instances” of the same method, if reference types in type parameters correspond to any other reference types, and value types are exactly the same. So, for example C<string>.M<int>() shares code with C<object>.M<int>(), but not with C<string>.M<byte>(). There is no difference between type type parameters and method type parameters. (The original paper from 2001 mentions that code can be shared also when both parameters are structs with the same layout, but I'm not sure this is true in the actual implementation.)
Let's make an intermediate step on our way to generic methods: non-generic methods in generic types. Because of code sharing, we need to get the type parameters from somewhere (e.g. for calling code like new T[]). For this reason, each instantiation of generic type (e.g. C<string> and C<object>) has its own type handle, which contains the type parameters and also method table. Ordinary methods can access this type handle (technically a structure confusingly called MethodTable, even though it contains more than just the method table) from the this reference. There are two types of methods that can't do that: static methods and methods on value types. For those, the type handle is passed in as a hidden argument.
For non-virtual generic methods, the type handle is not enough and so they get different hidden argument, MethodDesc, that contains the type parameters. Also, the compiler can't store the instantiations in the ordinary method table, because that's static. So it creates a second, different method table for generic methods, which is indexed by type parameters, and gets the method address from there, if it already exists with compatible type parameters, or creates a new entry.
Virtual generic methods are now simple: the compiler doesn't know the concrete type, so it has to use the method table at runtime. And the normal method table can't be used, so it has to look in the special method table for generic methods. Of course, the hidden parameter containing type parameters is still present.
One interesting tidbit learned while researching this: because the JITer is very lazy, the following (completely useless) code works:
object Lift<T>(int count) where T : new()
{
if (count == 0)
return new T();
return Lift<List<T>>(count - 1);
}
The equivalent C++ code causes the compiler to give up with a stack overflow.
Yes. The code for specific type is generated at the runtime by CLR and keeps a hashtable (or similar) of implementations.
Page 372 of CLR via C#:
When a method that uses generic type
parameters is JIT-compiled, the CLR
takes the method's IL, substitutes the
specified type arguments, and then
creates native code that is specific
to that method operating on the
specified data types. This is exactly
what you want and is one of the main
features of generics. However, there
is a downside to this: the CLR keeps
generating native code for every
method/type combination. This is
referred to as code explosion. This
can end up increasing the
application's working set
substantially, thereby hurting
performance.
Fortunately, the CLR has some
optimizations built into it to reduce
code explosion. First, if a method is
called for a particular type argument,
and later, the method is called again
using the same type argument, the CLR
will compile the code for this
method/type combination just once. So
if one assembly uses List,
and a completely different assembly
(loaded in the same AppDomain) also
uses List, the CLR will
compile the methods for List
just once. This reduces code explosion
substantially.
EDIT
I now came across I now came across https://msdn.microsoft.com/en-us/library/sbh15dya.aspx which clearly states that generics when using reference types are reusing the same code, thus I would accept that as the definitive authority.
ORIGINAL ANSWER
I am seeing here two disagreeing answers, and both have references to their side, so I will try to add my two cents.
First, Clr via C# by Jeffrey Richter published by Microsoft Press is as valid as an msdn blog, especially as the blog is already outdated, (for more books from him take a look at http://www.amazon.com/Jeffrey-Richter/e/B000APH134 one must agree that he is an expert on windows and .net).
Now let me do my own analysis.
Clearly two generic types that contain different reference type arguments cannot share the same code
For example, List<TypeA> and List<TypeB>> cannot share the same code, as this would cause the ability to add an object of TypeA to List<TypeB> via reflection, and the clr is strongly typed on genetics as well, (unlike Java in which only the compiler validates generic, but the underlying JVM has no clue about them).
And this does not apply only to types, but to methods as well, since for example a generic method of type T can create an object of type T (for example nothing prevents it from creating a new List<T>), in which case reusing the same code would cause havoc.
Furthermore the GetType method is not overridable, and it in fact always return the correct generic type, prooving that each type argument has indeed its own code.
(This point is even more important than it looks, as the clr and jit work based on the type object created for that object, by using GetType () which simply means that for each type argument there must be a separate object even for reference types)
Another issue that would result from code reuse, as the is and as operators will no longer work correctly, and in general all types of casting will have serious problems.
NOW TO ACTUAL TESTING:
I have tested it by having a generic type that contaied a static member, and than created two object with different type parameters, and the static fields were clrearly not shared, clearly prooving that code is not shared even for reference types.
EDIT:
See http://blogs.msdn.com/b/csharpfaq/archive/2004/03/12/how-do-c-generics-compare-to-c-templates.aspx on how it is implemented:
Space Use
The use of space is different between C++ and C#. Because C++
templates are done at compile time, each use of a different type in a
template results in a separate chunk of code being created by the
compiler.
In the C# world, it's somewhat different. The actual implementations
using a specific type are created at runtime. When the runtime creates
a type like List, the JIT will see if that has already been
created. If it has, it merely users that code. If not, it will take
the IL that the compiler generated and do appropriate replacements
with the actual type.
That's not quite correct. There is a separate native code path for
every value type, but since reference types are all reference-sized,
they can share their implementation.
This means that the C# approach should have a smaller footprint on
disk, and in memory, so that's an advantage for generics over C++
templates.
In fact, the C++ linker implements a feature known as “template
folding“, where the linker looks for native code sections that are
identical, and if it finds them, folds them together. So it's not a
clear-cut as it would seem to be.
As one can see the CLR "can" reuse the implementation for reference types, as do current c++ compilers, however there is no guarantee on that, and for unsafe code using stackalloc and pointers it is probably not the case, and there might be other situations as well.
However what we do have to know that in CLR type system, they are treated as different types, such as different calls to static constructors, separate static fields, separate type objects, and a object of a type argument T1 should not be able to access a private field of another object with type argument T2 (although for an object of the same type it is indeed possible to access private fields from another object of the same type).
Note that the following are examples of the rare cases where dotNet reflector does not disassemble correctly. In the vast majority of cases it works perfectly, and I am not suggesting this is necessarily a bug in reflector. It may be a result of protection or obfuscation or unmanaged code on the assemblies in question.
I try to disassemble System.Web.UI.WebControls.XmlHierarchicalEnumerable in dotnet reflector. The generics seems all screwed up, eg:
// Nested Types
[CompilerGenerated]
private sealed class GetEnumerator>d__0 : IEnumerator<object>,
IEnumerator, IDisposable
{
// Fields
private int <>1__state;
private object <>2__current;
public XmlHierarchicalEnumerable <>4__this;
public IEnumerator <>7__wrap2;
public IDisposable <>7__wrap3;
public XmlNode <node>5__1;
In other assemblies I sometimes get little squares (I know these usually stand for 'unknown symbol') in place of class names, eg:
dictionary1.Add("autopostbackonselect", 0x34);
ᜀ.ᜌ = dictionary1;
}
if (ᜀ.ᜌ.TryGetValue(key, out num))
{
switch (num)
What gives ? Anyone know ?
In the first example, this is completely expected. These classes are used for the implementation of IEnumerable<T> when using the yield return statements. It generates classes which store the state and get the new values when MoveNext is called on the IEnumerator<T> instance output by the IEnumerable<T>.GetEnumerator implementation (you will note they are one in the same).
It should be noted that what you are seeing is completely legal naming syntax from a CLR perspective. From a C# perspective though, it is not legal. However, since these classes are internal and you will never need access to them directly (only through interface implmentations), there is no need for them to be legal C# names.
As for the second, I haven't seen that behavior, it's possible that the assembly is obfuscated, but I've not seen that in .NET in any version. If you clarify the assemblies (.NET framework or not) in which version of the .NET framework you are looking at, as well as what version of reflector you are using, it would help.
I have seen this before when looking at assemblies that have been Obfuscated. Quite often during this process variable names are unreadable to the human eye, thus resulting in a unknown character.
This assembly might have been Obfuscated, you can check these links http://cooprotector.com/ http://intelliside.com/
There's quite a few things being autogenetated by the compiler. Auto properties, anonymous types/methods and emumerators based on enumerator blocks. They All need a name and that should be one that does not clash with something names by the developer. Since <>_ is a perfectly legal name in CLR terms but not in C# prefixing anything autogenetated and named with <>_ ensures that the compiler wont accidentally choose a name already used by the developer.
I don't mean dynamic casting in the sense of casting a lower interface or base class to a more derived class, I mean taking an interface definition that I've created, and then dynamically casting to that interface a different object NOT derived from that interface but supporting all the calls.
For example,
interface IMyInterface
{
bool Visible
{
get;
}
}
TextBox myTextBox = new TextBox();
IMyInterface i = (dynamic<IMyInterface>)myTextBox;
This could be achieved at compile time for known types, and runtime for instances declared with dynamic. The interface definition is known, as is the type (in this example) so the compiler can determine if the object supports the calls defined by the interface and perform some magic for us to have the cast.
My guess is that this is not supported in C#4 (I was unable to find a reference to it), but I'd like to know for sure. And if it isn't, I'd like to discuss if it should be included in a future variant of the language or not, and the reasons for and against. To me, it seems like a nice addition to enable greater polymorphism in code without having to create whole new types to wrap existing framework types.
Update
Lest someone accuse me of plagiarism, I was not aware of Jon Skeet having already proposed this. However, nice to know we thought of exceedingly similar syntax, which suggests it might be intuitive at least. Meanwhile, "have an original idea" remains on my bucket list for another day.
I think Jon Skeet has had such a proposal (http://msmvps.com/blogs/jon_skeet/archive/2008/10/30/c-4-0-dynamic-lt-t-gt.aspx), but so far, I haven't heard that C# 4.0 is going to have it.
I think that's problematic. You are introducing coupling between two classes which are not coupled.
Consider the following code.
public interface IFoo
{
int MethodA();
int MethodB();
}
public class Bar
{
int MethodA();
int MethodB();
}
public class SomeClass
{
int MethodFoo(IFoo someFoo);
}
should this then be legal?
int blah = someClass.MethodFoo((dynamic<IFoo>)bar);
It seems like it should be legal, because the compiler should be able to dynamically type bar as something that implements IFoo.
However, at this point you are coupling IFoo and Bar through a call in a completely separate part of your code.
If you edit Bar because it no longer needs MethodB, suddenly someClass.MethodFood doesn't work anymore, even though Bar and IFoo are not related.
In the same way, if you add MethodC() to IFoo, your code would break again, even though IFoo and Bar are ostensibly not related.
The fact is, although this would be useful in select cases where there are similarities amongst objects that you do not control, there is a reason that interfaces have to be explicitly attached to objects, and the reason is so that the compiler can guarantee that the object implements it.
There is no need for C# to support this, as it can be implemented very cleanly as library.
I've seen three or four separate implementations (I started writing one myself before I found them). Here's the most thorough treatment I've seen:
http://bartdesmet.net/blogs/bart/archive/2008/11/10/introducing-the-c-ducktaper-bridging-the-dynamic-world-with-the-static-world.aspx
It will probably be even easier to implement once the DLR is integrated into the runtime.
Because the wrapper/forwarder class for a given interface can be generated once and then cached, and then a given object of unknown type can be wrapped once, there is a lot of scope for caching of call sites, etc. so the performance should be excellent.
In contrast, I think the dynamic keyword, which is a language feature, and a hugely complex one, is an unnecessary and potentially disastrous digression, shoe-horned into a language that previously had a very clear static typing philosophy, which gave it an obvious direction for future improvement. They should have stuck to that and made the type inference work better and better until typing became more invisible. There are so many areas where they could evolve the language, without breaking existing programs, and yet they don't, simply due to resource constraints (e.g. the reason var can't be used in more places is because they would have to rewrite the compiler and they don't have time).
They are still doing good stuff in C# 4.0 (the variance features) but there is so much else that could be to be done to make the type system smarter, more automatic, more powerful at detecting problems at compile time. Instead, we're essentially getting a gimmick.
The opensource framework Impromptu-Interface does this using the C# 4 and the dlr.
using ImpromptuInterface;
interface IMyInterface
{
bool Visible
{
get;
}
}
TextBox myTextBox = new TextBox();
IMyInterface i = myTextBox.ActLike<IMyInterface>();
Since it uses the dlr it will also work with ExpandoObject and DynamicObject.