繁体   English   中英

`typeof`运算符如何在泛型方法中获取类型参数?

[英]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)?

不,不。 泛型方法的主体在运行时即时生成。 因此,例如,当您将Tint ,将生成以下方法:

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

每次传递不同类型时都会发生这种情况。 但是如果再次使用相同的类型,CLR将缓存先前生成的方法并执行它,而不是生成新方法。

在.NET中,泛型不会被删除。 CLR一直实现泛型到字节代码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM