具有类型推断的泛型和非泛型方法重载规则

本文关键字:泛型方法 重载 规则 泛型 类型 | 更新日期: 2023-09-27 18:18:27

给定以下两个重载方法签名:

public B DoSomething<A,B>(A objOne, B objTwo)
public object DoSomething(object objOne, Type objType);

我希望调用this会调用第二个签名,但它不是:

var obj = new SomeType();
var type = typeof(SomeOtherType);
DoSomething(obj, type);

在我看来,看一下规范,第二个重载更适用(有一个确切的类型和较小的密度)。但是,它不会被调用。相反,调用第一个重载时,A的类型为object, B的类型为Type。为什么会这样,除了重命名方法或使用命名参数之外,是否有一种方法可以调用此方法?

编辑:

以下是我在7.5.3.2中引用的规范的部分:

如果参数类型序列{P1, P2,…,PN}和{Q1, Q2,…,QN}是等价的(即每个Pi都有一个单位变换到相应的Qi),为了确定更好的函数成员,应用以下打破规则。

  • 如果MP是非泛型方法,而MQ是泛型方法,则MP优于MQ。
  • 否则,如果MP比MQ具有更具体的参数类型,则MP优于MQ。设{R1, R2,…,RN}和{S1, S2,…,SN}分别表示MP和MQ的未实例化和未展开的参数类型。如果对于每个参数,RX不低于SX,并且对于至少一个参数,RX比SX更具体,则MP的参数类型比MQ的参数类型更具体:
    • 类型参数没有非类型参数那么具体。

具有类型推断的泛型和非泛型方法重载规则

编辑完成后,这里是编译器选择的方法

DoSomething<SomeType,Type>(SomeType o, Type t)
DoSomething(object o,Type t);

正如规范中所说的选择更好的函数成员:

给定一个参数列表A,其中包含一组参数表达式{E1, E2,…和两个适用的函数成员MP和MQ带参数类型{P1, P2,…, PN}和{Q1, Q2,…, QN}, MP定义为a 优于MQ •至少有一个论点是正确的从EX到PX的转换优于从EX到QX的转换。

泛型法从SomeTypeSomeType的转化效果优于非泛型法从SomeTypeobject的转化效果。如果非泛型方法定义为

DoSomething(SomeType o, Type t);

则没有更好的转换参数,您将落入case:

如果参数类型序列{P1, P2,…,PN}和{Q1, Q2,…,QN}是等价的

第一个规则将选择非泛型方法:

•如果MP是非泛型方法,而MQ是泛型方法,则MP是


注意:在你编辑问题之前,有一个类型为object的第一个参数,泛型方法是
DoSomething<object,Type>(object o, Type t)

同样,在这种情况下,参数序列是等效的,并且选择非泛型方法。

在我的测试中,我能够使用强制转换来获得您想要的分辨率。DoSomething((object)"1234", typeof(string));

呼叫DoSomething<object, SomeType>(obj, type)();