How Different Are Templates from Generics

Ahmet Sait nightmarex1337 at hotmail.com
Fri Oct 11 22:34:33 UTC 2019


On Friday, 11 October 2019 at 17:50:42 UTC, Jonathan M Davis 
wrote:
> Generic functions and types operate on Object underneath the 
> hood. If you have Container<Foo> and Container<Bar>, you really 
> just have Container<Object> with some syntactic niceties to 
> avoid explicit casts. You get type checks to ensure that 
> Container<Foo> isn't given a Bar unless Bar is derived from 
> Foo, and the casts to and from Object when giving 
> Container<Foo> a Foo are taken care of for you, but it's still 
> always Container<Object> underneath the hood.
>
> In the case of Java, the type of T in Container<T> or foo<T>() 
> is truly only a compile time thing, so the bytecode only has 
> Container<Object> and no clue what type is actually supposed to 
> be used (the casts are there where the container or function is 
> used, but the container or function has no clue what the type 
> is; it just sees Object). That makes it possible to cheat with 
> reflection and put something not derived from Foo in 
> Container<Foo> but will then usually result in runtime failures 
> when the casts the compiler inserted are run. C# doesn't have 
> that kind of type erasure in that the information that 
> Container<Foo> contains Foo rather than Object is maintained at 
> runtime, but you still have a Container<Object>. It's just a 
> Container<Object> with some metadata which keeps track of the 
> fact that for this particular object of Container<Object>, 
> Object is always supposed to be a Foo. As I'm a lot less 
> familiar with C# than Java, I'm not all that familiar with what 
> the practical benefits that gives are, though I'd expect that 
> it would mean that reflection code would catch when you're 
> trying to put a Bar into Container<Foo> and wouldn't let you.
>
> Note that for generics to work, they have to a common base 
> type, and you only ever get one version of a generic class or 
> function even if it gets used with many different types derived 
> from Object. For a primitive type like int or float (as well as 
> for structs in the case of C#), they have to be put into a type 
> derived from Object in order to be used with generics (as I 
> expect you're aware, C# calls this boxing and unboxing). 
> Templates don't act like this at all.

Unlike Java, C# actually does generate different code pieces for 
different value types [1] and reuses the same generated code for 
reference types.

[1] 
https://alexandrnikitin.github.io/blog/dotnet-generics-under-the-hood/


More information about the Digitalmars-d-learn mailing list