6

假设我有一个通用方法:

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?或者它也取决于其他东西?

4

3 回答 3

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必须提前满足任何约束)。如果有 value-type T,那么每个泛型类型参数的组合在运行时都会得到一个单独的实现,因为每个组合都需要不同的最终实现。

于 2012-04-23T10:46:59.470 回答
4

这取决于所涉及的类型。

对于所有引用类型(即classes),一种方法将被 JITted 来处理它们。

对于所有值类型(即structs),每种类型的一个方法将被 JITted。

所以问题中的信息不够详细,无法回答,如果FeatureCategory是引用类型,那么是的,将为它们 JITted 一种方法。如果其中之一或两者都是值类型,则每种值类型的一个方法将被 JITted。

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

流行测验:如果您NGEN在具有泛型类型/方法的程序集上使用会发生什么?(提示:不是你想的那样

于 2012-04-23T10:46:43.713 回答
0

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

于 2012-04-23T10:42:15.500 回答