C# `typeof`运算符如何在泛型方法中获取类型参数?
在Java中,此代码不起作用:C# `typeof`运算符如何在泛型方法中获取类型参数?,c#,C#,在Java中,此代码不起作用: public <T> void foo() { print(T.class); } // compile time error 但在C#中,我可以在运行时获取类型参数: public void Foo<T>() { print(typeof(T)); } 由于ldtoken是一条“将元数据令牌转换为其运行时表示形式”的指令,因此T的运行时类型显然存储为元数据 我猜每个方法都有自己的“元数据表”(或者类似的东西),因此调用Foo()和F
public <T> void foo() { print(T.class); } // compile time error
但在C#中,我可以在运行时获取类型参数:
public void Foo<T>() { print(typeof(T)); }
由于ldtoken
是一条“将元数据令牌转换为其运行时表示形式”的指令,因此T
的运行时类型显然存储为元数据
我猜每个方法都有自己的“元数据表”(或者类似的东西),因此调用
Foo()
和Foo()
将生成两个“方法句柄”和两个“元数据表”,但共享相同的机码。是吗?在.NET中,泛型不会被删除。CLR实现泛型,一直到字节码
编译器(或vm)是否自动将void Foo()转换为void Foo(类型T)
不,没有。泛型方法的主体是在运行时动态生成的。因此,例如,当您将T
作为int
提供时,将生成此方法:
public void Foo<int>() { print(typeof(int)); }
public void Foo(){print(typeof(int));}
每次通过不同的类型时都会发生这种情况。但是如果您再次使用相同的类型,CLR将缓存先前生成的方法并执行它,而不是生成新的方法。您的最后一点不太正确。CLR为每个值类型生成新的运行时方法,但对所有引用类型只生成一个。解释说。。。(您可能已经在研究中看到过)Java在运行时强制使用泛型类型系统,而运行时不知道泛型。C#的情况并非如此。在C#中,运行时和语言都是为了支持泛型而编写的。
ldtoken !!T
call System.Type System.Type::GetTypeFromHandle(System.RuntimeTypeHandle)
public void Foo<int>() { print(typeof(int)); }