In Java, this code doesn't work:
public <T> void foo() { print(T.class); } // compile time error
Beacuse the generic type T
is erased at runtime. To use T
, I must use it as an argument, which will push String.class
into stack
public <T> void foo(Class<T> T) { print(T); }
public void bar() { foo(String.class); }
But in C#, I can get type argument at runtime:
public void Foo<T>() { print(typeof(T)); }
How does it work? Does the compiler (or vm) automatically translate void Foo<T>()
to void Foo(Type T)
?
update:
I disassembled the bytecode and got something like:
ldtoken !!T
call System.Type System.Type::GetTypeFromHandle(System.RuntimeTypeHandle)
Since ldtoken
is an instruction which "Convert metadata token to its runtime representation", it's clear that the runtime type of T
is stored as metadata.
I guess each method has it's own "metadata table" (or something like that), so calling Foo<string>()
and Foo<object>()
will generate two "method handle" and two "metadata table", but share the same machine code. Is it?