6

我有两个重载的泛型方法:

T Foo<T>(T t) { Console.WriteLine("T"); return t; }

T Foo<T>(int i) { Console.WriteLine("int"); return default(T); }

当我尝试Foo在我的计算机上按以下方式调用时:

Foo(5);

我没有收到编译器错误或警告,并且调用了带有通用参数的第一个方法(即输出为T)。在所有 C# 化身和所有平台上都会出现这种情况吗?在那种情况下,为什么?

另一方面,如果我在泛型调用中明确指定类型:

Foo<int>(5);

调用带有参数的第二种方法int,即输出为 now int为什么?

我在我的两个方法重载中使用了不同的参数名称,因此以下调用的输出符合预期:

Foo<int>(t: 5);       // output 'T'
Foo<int>(i: 5);       // output 'int'

如果我调用第一种方法,我什至可以省略类型说明:

Foo(t: 5);            // output 'T'

但是如果我尝试编译这个:

Foo(i: 5);

我收到一个错误无法从用法中推断出方法“Foo(int)”的类型参数。尝试明确指定类型参数。 为什么编译器不能处理这个调用?

注意这些测试是在 Windows 8 x64 系统上使用LinqPad执行的(如果与结果相关...)

4

1 回答 1

7

最后一个问题

由于您指定(通过参数名称)它应该调用带int参数的重载,因此编译器不知道要传递什么T

第一个问题

因此,Foo(5) 仅匹配一个重载( Foo<T>())。
因此,它必须只调用Foo<T>().

第二个问题

当您显式指定类型参数 ( <int>) 时,两种重载都适用。
在这种情况下,Foo(int)更好,因为它的参数不是泛型类型。

根据 C# 规范§7.5.3.2:

  • 否则,如果 MP 比 MQ 具有更具体的参数类型,则 MP 优于 MQ。令 {R1, R2, ..., RN} 和 {S1, S2, ..., SN} 表示 MP 和 MQ 的未实例化和未扩展的参数类型。MP 的参数类型比 MQ 的更具体,如果对于每个参数,RX 不比 SX 更具体,并且,对于至少一个参数,RX 比 SX 更具体:
    • 类型参数不如非类型参数具体。

(重点补充)

于 2013-05-21T14:59:12.340 回答