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

时间:2012-04-23 10:40:39

标签: c# generics generic-method

假设我有一个通用方法:

void Fun<T>(FunArg arg) {}

通用方法的this.Fun<Feature>this.Fun<Category>是否有不同的实例?

通常,泛型方法如何实例化?不同的泛型参数会产生不同的方法,或者同一个方法以及在运行时使用的不同元数据吗?

请使用语言规范中的一些引用来支持您的回答。

另外,假设我这样做了:

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

然后,

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

lineX是否撤消了我在line1处所做的事情?或者它还取决于其他人呢?

3 个答案:

答案 0 :(得分:5)

它们共享方法定义,但在运行时它们是不同的MethodInfo - 因为泛型类型参数定义一般方法。

支持插图:

    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

在JIT级别,它更复杂;任何引用类型参数将共享一个实现,因为引用是引用是一个引用(注意所有这样的T必须提前满足任何约束)。如果存在值类型T,则泛型类型参数的每个组合在运行时都会获得单独的实现,因为每个实现都需要不同的最终实现。

答案 1 :(得分:4)

这取决于所涉及的类型。

对于所有引用类型(即),一个方法将被JIT以处理它们。

对于所有值类型(即。结构),一个方法类型将被JIT。

因此,问题中的信息不够详细,如果FeatureCategory是引用类型,那么是的,一个方法将为它们进行JIT。如果其中一个或两个都是值类型,则每个值类型的一个方法将被JIT。

请注意我在这里使用 JITted 这个词。在编译的程序集中,只有一个方法,但在运行时,JITter将根据上述规则创建泛型方法的实际实现。

流行测验:如果在具有泛型类型/方法的程序集上使用NGEN会发生什么? (提示:not what you think

答案 2 :(得分:0)

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