Question

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(5);

I get no compiler errors or warnings, and the first method with the generic argument is called (i.e. the output is T). Will this be the case in all C# incarnations and on all platforms? 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, i.e. the output is now 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. 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...)

Was it helpful?

Solution

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.

First question

Because of this, Foo(5) only matches one overload (Foo<T>()).
Therefore, it must only call Foo<T>().

Second question

When you explicitly specify a type argument (<int>), both overloads are applicable.
In that case, Foo(int) is better, since its parameter is not of generic type.

As per the C# spec §7.5.3.2:

  • Otherwise, if MP has more specific parameter types than MQ, then MP is better than MQ. Let {R1, R2, …, RN} and {S1, S2, …, SN} represent the uninstantiated and unexpanded parameter types of MP and 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:
    • A type parameter is less specific than a non-type parameter.

(emphasis added)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top