【发布时间】:2019-02-10 05:46:40
【问题描述】:
在 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>() 将生成两个“方法句柄”和两个“元数据表”,但共享相同的机器代码.是吗?
【问题讨论】:
-
stackoverflow.com/questions/355060/c-sharp-vs-java-generics 解释说...(您也可能已经在研究中看到过)
-
Java 在不知道泛型的运行时强加了泛型类型系统。这不是 C# 的情况。在 C# 中,运行时和语言都是为支持泛型而编写的。
标签: c#