Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does `typeof` operator get type argument in generic methods?

Tags:

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?

like image 478
yyyy Avatar asked Feb 10 '19 05:02

yyyy


People also ask

What operator is used to obtain the type of a specific object?

The typeof is an operator keyword which is used to get a type at the compile-time. Or in other words, this operator is used to get the System. Type object for a type. This operator takes the Type itself as an argument and returns the marked type of the argument.

How does typeof work in C#?

typeof() is an operator in C#, it is used to get the type (system type) of with class name of a given type. By using typeof() operator, we can get the name of the type, namespace name. It works with only compile-time known types. typeof() operator does not work with the variables or instances.

What does typeof return in C?

In other languages, such as C# or D and, to some degree, in C (as part of nonstandard extensions and proposed standard revisions), the typeof operator returns the static type of the operand. That is, it evaluates to the declared type at that instant in the program, irrespective of its original form.

What is a generic type parameter?

Generic Methods A type parameter, also known as a type variable, is an identifier that specifies a generic type name. The type parameters can be used to declare the return type and act as placeholders for the types of the arguments passed to the generic method, which are known as actual type arguments.


1 Answers

Does the compiler (or vm) automatically translate void Foo() to void Foo(Type T)?

No it doesn't. The body for generic methods is generated at runtime, on the fly. So, for example, when you supply T as int, this method is generated:

public void Foo<int>() { print(typeof(int)); }

This happens every time you pass a different type. But if you use the same type again the CLR will cache the previously generated method and execute it, instead of generating a new one.

like image 155
Selman Genç Avatar answered Oct 06 '22 01:10

Selman Genç