简体   繁体   English

通用方法重载和优先级

[英]Generic method overloading and precedence

I have two overloaded generic methods: 我有两个重载的泛型方法:

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

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

When I try to call Foo as follows on my computer: 当我尝试在计算机上调用Foo

Foo(5);

I get no compiler errors or warnings, and the first method with the generic argument is called (ie the output is T ). 我没有得到编译器错误或警告,并调用带泛型参数的第一个方法(即输出为T )。 Will this be the case in all C# incarnations and on all platforms? 在所有C#化身和所有平台上都会出现这种情况吗? In that case, why? 在那种情况下,为什么?

On the other hand, if I explicitly specify the type in the generic call: 另一方面,如果我在泛型调用中明确指定类型:

Foo<int>(5);

the second method with the int argument is called, ie the output is now int . 调用带有int参数的第二个方法,即输出现在是int Why? 为什么?

I am using different argument names in my two method overloads, so the output from the following calls are as expected: 我在两个方法重载中使用不同的参数名称,因此以下调用的输出是预期的:

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

If I am calling the first method, I can even leave out the type specification: 如果我调用第一种方法,我甚至可以省略类型规范:

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

But if I try to compile this: 但是,如果我尝试编译这个:

Foo(i: 5);

I get an error The type arguments for method 'Foo(int)' cannot be inferred from the usage. 我得到一个错误方法'Foo(int)'的类型参数不能从用法中推断出来。 Try specifying the type arguments explicitly. 尝试显式指定类型参数。 Why cannot the compiler deal with this call? 为什么编译器不能处理这个调用?

Note These tests have been performed with LinqPad on a Windows 8 x64 system (in case that is relevant to the results...) 注意这些测试是在Windows 8 x64系统上使用LinqPad执行的(如果与结果相关...)

Last question 最后一个问题

Since you specified (by parameter name) that it should call the overload that takes an int parameter, the compiler has no idea what to pass for T . 由于您指定(通过参数名称)它应该调用带有int参数的重载,因此编译器不知道要为T传递什么。

First question 第一个问题

Because of this, Foo(5) only matches one overload ( Foo<T>() ). 因此, Foo(5) 只匹配一个重载Foo<T>() )。
Therefore, it must only call Foo<T>() . 因此,它必须只调用Foo<T>()

Second question 第二个问题

When you explicitly specify a type argument ( <int> ), both overloads are applicable. 显式指定类型参数( <int> )时,两个重载都适用。
In that case, Foo(int) is better, since its parameter is not of generic type. 在这种情况下, Foo(int)更好,因为它的参数不是泛型类型。

As per the C# spec §7.5.3.2: 根据C#规范§7.5.3.2:

  • Otherwise, if MP has more specific parameter types than MQ, then MP is better than MQ. 否则,如果MP具有比MQ更多的特定参数类型,则MP优于MQ。 Let {R1, R2, …, RN} and {S1, S2, …, SN} represent the uninstantiated and unexpanded parameter types of MP and MQ. 设{R1,R2,...,RN}和{S1,S2,...,SN}表示MP和MQ的未实例化和未展开的参数类型。 MP's parameter types are more specific than MQ's if, for each parameter, RX is not less specific than SX, and, for at least one parameter, RX is more specific than SX: MP的参数类型比MQ更具体,如果对于每个参数,RX的特定性不低于SX,并且对于至少一个参数,RX比SX更具体:
    • A type parameter is less specific than a non-type parameter. 类型参数不是非类型参数的特定参数。

(emphasis added) (重点补充)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM