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