General Method Resolution

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, a non-generic DoSomething method will be called. 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 changed is adding the T type parameter to the second overload, which makes it common. Note that the type parameter is not used.

This modification calls the first DoSomething method. What for? The compiler has all the information he needs to select the second method.

Could you explain why, or even better, point me to the C # specification section that explains this behavior?

+5
source share
2 answers

In your call, you do not specify a type argument - therefore, the compiler would have to specify a type T It cannot do this for your second method, because a type parameter is never mentioned in declared parameters. Therefore, this overload is not applicable and is ignored.

If you specify a type argument to call, for example. any of

 DoSomething<int>(1) DoSomething<object>(1) DoSomething<string>(1) 

... then in all cases a second overload will be called.

From section 7.6.5.1 of the C # 5 specification (method calls) when constructing a set of candidate methods:

  • If F is generic and M does not have a list of type arguments, F is a candidate when:
    • Type inference (Β§7.5.2) succeeds by listing the type arguments to invoke and
    • When the inferred type arguments are replaced by the corresponding method type parameters, all constructed types in the parameter list F satisfy their restrictions (Β§4.4.4), and the parameter list F is applicable with respect to A (Β§ 7.5.3.1).

As type inference does not work, the second method is not in the set of candidates, so by the time we get to the real resolution of overloading, the set has only one method (the first).

+10
source

the compiler cannot determine the type of the template in the DoSomething (1) call, but if you specify [int], another method will be selected.

-1
source

Source: https://habr.com/ru/post/1200610/


All Articles