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

时间:2014-08-18 18:57:46

标签: c# generics overloading

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

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

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

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

DoSomething(obj, type);

在我看来,看看规范,第二个过载更适用(有一个确切的类型和较小的arity)。但是,它不会被调用。而是调用第一个重载,其中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的未实例化和未展开的参数类型。 MP的参数类型比MQ更具体,如果对于每个参数,RX的特定性不低于SX,并且对于至少一个参数,RX比SX更具体:
    • 类型参数的特定性低于非类型参数。
    • ...

3 个答案:

答案 0 :(得分:1)

在此编辑之后是编译器在

之间进行选择的方法
DoSomething<SomeType,Type>(SomeType o, Type t)
DoSomething(object o,Type t);

正如规范所说,选择更好的功能成员:

  

给定参数列表A,其中包含一组参数表达式{E1,E2,   ...,EN}和两个适用的函数成员MP和MQ带参数   类型{P1,P2,...,PN}和{Q1,Q2,...,QN},MP定义为   如果是,则更好的功能成员比MQ更好   •对于至少一个论点,   从EX到PX的转换优于从EX到QX的转换。

SomeTypeSomeType的非通用方法转换,通用方法可以更好地从SomeType转换为object。如果将非泛型方法定义为

DoSomething(SomeType o, Type t);

然后就没有任何更好转换的论据,你将陷入案例:

  

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

第一条规则选择非通用方法:

  

•如果MP是非泛型方法而MQ是通用方法,则MP是   比MQ好。


注意:在编辑问题之前,有第一个类型为object的参数,而泛型方法是

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

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

答案 1 :(得分:-2)

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

答案 2 :(得分:-3)

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