Thursday 23 December 2010

typeof operator

Following last week's entry about Generics, I was thinking about the usage of C#'s typeof operator with generic types. You can do typeof(string) same as you can do typeof(T), so this brings up the question, how is typeof implemented?

When used with a non generic type, maybe one could think of typeof as an alias for a new Type("type name"). Well, first, this could not work for Generic types, cause these are only known at runtime, not at compile time... and second, the Type class has just a protected parameterless constructor.

So I compiled a few lines of code and launched Reflector on the output, coming up with this:

c#

Type tp = typeof(String);


IL

L_0001: ldtoken string
L_0006: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
L_000b: stloc.0



c#

Type tp = typeof(T);


IL

L_0001: ldtoken !T
L_0006: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
L_000b: stloc.0


so the same approach is used for both cases, involving a struct that was unknown to me, RuntimeTypeHandle, the Type.GetTypeFromHandle method and the ldtoken IL instructions.

Anyway, the most interesting of this is still the compile time/run time difference. For the non generic case, the token to load on top of the stack is already known at compile time, but for the generic case, the real value for T is know at runtime, and as we saw in the previous blog entry, the native code that will be generated for different concrete instantiations of the Generic type will be the same.
I presume the real T token is stored somewhere in the MethodTable (there's one for each instantiation) and taken from there.

No comments:

Post a Comment