当我声明这样的方法时:
void DoWork<T>(T a) { }
void DoWork(int a) { }
用这个称呼它:
int a = 1;
DoWork(a);
它会调用什么DoWork
方法?为什么?我似乎无法在任何MSDN文档中找到它。
答案 0 :(得分:9)
正如Eric Lippert says:
C#规范说明当你在调用
ReallyDoIt<string>(string)
和ReallyDoIt(string)
之间做出选择时 - 也就是说,当选择在两个具有相同签名的方法之间时,但是一个通过泛型替换获得该签名 - 然后我们在“替代”签名上选择“自然”签名。
更新:
我们在C#规范(7.5.3)中有什么:
如果在未指定类型参数的情况下调用泛型方法,则类型推断过程会尝试推断调用的类型参数。通过类型推断,类型参数int由方法的参数确定。类型推断作为方法调用的绑定时处理的一部分发生,并且发生before
调用的重载决策步骤。
如果在方法调用中指定了特定方法组,并且未将任何类型参数指定为方法调用的一部分,则会将类型推断应用于方法组中的每个泛型方法。如果类型推断成功,则推断的类型参数用于确定后续重载解析的参数类型。如果重载解析选择泛型方法作为要调用的方法,则推断的类型参数将用作调用的实际类型参数。如果特定方法的类型推断失败,则该方法不参与重载解析。
所以在重载解析之前,我们在方法组中有两个方法。一个DoWork(int)
和其他推断的DoWork<int>(int)
。
我们转到7.5.3.2(更好的功能成员):
如果参数类型序列{P1,P2,...,PN}和{Q1,Q2,...,QN}是等效的(即每个Pi具有到相应Qi的标识转换),则以下打破平局规则按顺序应用,以确定更好的功能成员。 1)如果MP是非泛型方法而MQ是泛型方法,则MP优于MQ。