3 ms·
C# doesn't erase types, and it doesn't create a separate type for every possible variant. See the ".Net Implementation" section here: http://www.jprl.com/Blog
by AndrewDucker 12y ago
C# doesn't erase types, and it doesn't create a separate type for every possible variant.
See the ".Net Implementation" section here:
http://www.jprl.com/Blog/archive/development/2007/Aug-31.html http://www.jprl.com/Blog/archive/development/2007/Aug-31.htm...
- pjmlp 12y agoThis interview with Anders Hejlsberg is also a good source of information http://www.artima.com/intv/generics.html http://www.artima.com/intv/generics.html
- qznc 12y agoSo, C# does instantiation, but is usually clever about reference types. I am not quite sure from the interview what happens about constraint types. It seems the reference is cast into an Interface type (IComparable) and used as such. In other words, boxing.
- michielvoo 12y agoThe arguments used for contrained type parameters can be checked by the compiler, so no casting is necessary at runtime "... C# does strong type checking when you compile the generic type. For an unconstrained type parameter, like List<T>, the only methods available on values of type T are those that are found on type Object, because those are the only methods we can generally guarantee will exist. So in C# generics, we guarantee that any operation you do on a type parameter will succeed." Edit (more explicit quote): "When you say K must implement IComparable, a couple of things happen. On any value of type K, you can now directly access the interface methods without a cast, because semantically in the program it's guaranteed that it will implement that interface. Whenever you try and create an instantiation of that type, the compiler will check that any type you give as the K argument implements IComparable, or else you get a compile time error." Furthermore (related to the CLR avoiding boxing costs): "I'm just pointing out that we do fairly aggressive code sharing where it makes sense, but we are also very conscious about not sharing where you want the performance. Typically with value types, you really do care that List<int> is int. You don't want them to be boxed as Objects. Boxing value types is one way we could share, but boy it would be an expensive way."
- qznc 12y agoWhat I wonder is: Take "SortedList<T> where T:IComparable". Now there is a generic add(T t) method, which needs to call t.compareTo(x). As add does not know the dynamic type of t, we don't know the vtable offset of compareTo for compilation. Thus the compareTo call cannot be compiled to "load method pointer from vtable; call it". We need something more expensive or JIT magic (traces,guards,etc).
- qznc 12y agoWhat I wonder is: Take "SortedList<T> where T:IComparable". Now there is a generic add(T t) method, which needs to call t.compareTo(x). As add does not know the dynamic type of t, we don't know the vtable offset of compareTo for compilation. Thus the compareTo call cannot be compiled to "load method pointer from vtable; call it". We need something more expensive or JIT magic (traces,guards,etc).
- zwieback 12y agoThe .NET generics are also interesting to contrast with C++ and Java since they are implemented in a virtual machine that allows interoperation between different languages. Not really applicable to the Go discussion, though.
- pjmlp 12y agoBoth Java and .NET also have a ahead of time compilation to native code.