[英]How does `typeof` operator get type argument in generic methods?
在Java中,此代码不起作用:
public <T> void foo() { print(T.class); } // compile time error
因为通用类型T
在运行时被删除。 要使用T
,我必须将它用作参数,这会将String.class
推入堆栈
public <T> void foo(Class<T> T) { print(T); }
public void bar() { foo(String.class); }
但在C#中,我可以在运行时获取类型参数:
public void Foo<T>() { print(typeof(T)); }
它是如何工作的? 编译器(或vm)是否自动将void Foo<T>()
为void Foo(Type T)
?
更新:
我反汇编了字节码,得到了类似的东西:
ldtoken !!T
call System.Type System.Type::GetTypeFromHandle(System.RuntimeTypeHandle)
由于ldtoken
是“将元数据令牌转换为其运行时表示”的指令,因此很明显T
的运行时类型存储为元数据。
我猜每个方法都有它自己的“元数据表”(或类似的东西),所以调用Foo<string>()
和Foo<object>()
将生成两个“方法句柄”和两个“元数据表”,但是共享相同的机器代码。 是吗?
编译器(或vm)是否自动将void Foo()转换为void Foo(Type T)?
不,不。 泛型方法的主体在运行时即时生成。 因此,例如,当您将T
为int
,将生成以下方法:
public void Foo<int>() { print(typeof(int)); }
每次传递不同类型时都会发生这种情况。 但是如果再次使用相同的类型,CLR将缓存先前生成的方法并执行它,而不是生成新方法。
在.NET中,泛型不会被删除。 CLR一直实现泛型到字节代码。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.