Consider the following code:
public class Tests
{
public void Test()
{
Assert.AreEqual("Int", DoSomething(1));
}
public static string DoSomething<T>(T value)
{
return "Generic";
}
public static string DoSomething(int value)
{
return "Int";
}
}
As expected, the non-generic DoSomething method will be invoked. Now consider the following modification:
public class Tests
{
public void Test()
{
Assert.AreEqual("Int", DoSomething(1));
}
public static string DoSomething<T>(T value)
{
return "Generic";
}
public static string DoSomething<T>(int value)
{
return "Int";
}
}
The only thing I've changed is adding the T type parameter to the second overload, thus making it generic. Note that the type parameter is not used.
That modification causes the first DoSomething method to be called. Why? The compiler has all the information it needs in order to choose the second method.
Can you please explain why, or even better, point me to the section of the C# specification that explains this behavior?
In your call, you're not specifying a type argument - so the compiler would have to infer the type of T
. It can't do that for your second method, because the type parameter is never mentioned in the declared parameters. Therefore, that overload is not applicable, and is ignored.
If you specify a type argument to the call, e.g. any of
DoSomething<int>(1)
DoSomething<object>(1)
DoSomething<string>(1)
... then in all cases the second overload will be called.
From section 7.6.5.1 of the C# 5 spec, (method invocations) when constructing the set of candidate methods:
- If F is generic and M has no type argument list, F is a candidate when:
- Type inference (§7.5.2) succeeds, inferring a list of type arguments for the call, and
- Once the inferred type arguments are substituted for the corresponding method type parameters, all constructed types in the parameter list of F satisfy their constraints (§4.4.4), and the parameter list of F is applicable with respect to A (§7.5.3.1).
As type inference doesn't succeed, the second method isn't in the candidate set, so by the time we get to real overload resolution, the set just has a single method in (the first one).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With