简体   繁体   English

泛型方法如何在C#中实例化?

[英]How generic methods gets instantiated in C#?

Suppose I've a generic method as: 假设我有一个通用方法:

void Fun<T>(FunArg arg) {}

Are this.Fun<Feature> and this.Fun<Category> different instantiations of the generic method? this.Fun<Feature>this.Fun<Category>是泛型方法的不同实例吗?

In general, how does the generic method get instantiated? 一般来说,泛型方法如何实例化? Different generic argument produces different method, or same method along with different metadata which is used at runtime? 不同的泛型参数会产生不同的方法,或者同一个方法以及在运行时使用的不同元数据?

Please support your answer with some quote(s) from the language specification. 请使用语言规范中的一些引用来支持您的回答。

Also, suppose I did these: 另外,假设我做了这些:

client.SomeEvent += this.Fun<Feature>;   //line1
client.SomeEvent += this.Fun<Category>;  //line2
client.SomeEvent += this.Fun<Result>;    //line3

then later on, 然后,

client.SomeEvent -= this.Fun<Feature>;   //lineX

Does the lineX undo the thing which I did at line1 ? 是否lineX撤消我在做的事情line1 Or it depends on somethig else also? 或者它还取决于其他人呢?

They all share a method definition , but at runtime they are different MethodInfo - because the generic type arguments define a generic method. 它们都共享一个方法定义 ,但在运行时它们是不同的MethodInfo - 因为泛型类型参数定义了一个泛型方法。

Supporting illustration: 支持插图:

    Action<FunArg> a1 = Fun<X>;
    Action<FunArg> a2 = Fun<Y>;
    Action<FunArg> a3 = Fun<Y>;
    Console.WriteLine(a1.Method == a2.Method); // false
    Console.WriteLine(a3.Method == a2.Method); // true

At the JIT level, it is more complex; 在JIT级别,它更复杂; any reference-type parameters will share an implementation, as a reference is a reference is a reference (noting that all such T must satisfy any constraints in advance). 任何引用类型参数都将共享一个实现,因为引用是引用是一个引用(注意所有这样的T必须提前满足任何约束)。 If there are value-type T , then every combination of generic type arguments gets a separate implementation at runtime, since each requires a different final implementation. 如果存在值类型T ,那么泛型类型参数的每个组合在运行时都会获得单独的实现,因为每个需要不同的最终实现。

It depends on the types involved. 这取决于所涉及的类型。

For all the reference types (ie. classes ), one method will be JITted to handle them all. 对于所有引用类型(即 ),将使用一种方法JIT来处理它们。

For all the value types (ie. structs ), one method per type will be JITted. 对于所有值类型(即结构 ), 每种类型的一个方法将被JITted。

So the information in the question is not detailed enough to answer, if Feature and Category are reference types, then yes, one method will be JITted for them. 所以问题中的信息不够详细,无法回答,如果FeatureCategory是引用类型,那么是的,一个方法将被JIT为它们。 If one of them, or both, are value types, one method per value type will be JITted. 如果其中一个或两者都是值类型,则每个值类型的一个方法将被JIT。

Note my use of the word JITted here. 请注意我在这里使用JITted这个词。 In the assembly compiled, there will be only one method, but at runtime, the JITter will create actual implementations of the generic methods according to the above rules. 在编译的程序集中,只有一个方法,但在运行时,JITter将根据上述规则创建泛型方法的实际实现。

Pop Quiz : What happens if you use NGEN on an assembly with generic types/methods? 流行测验 :如果在具有泛型类型/方法的程序集上使用NGEN会发生什么? (hint: not what you think ) (提示: 不是你的想法

是的,它们将成为两种不同的方法。

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

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