As Eric Lippert says :
The C # specification states that when you have a choice between calls to ReallyDoIt<string>(string) and ReallyDoIt(string) - that is, when you choose between two methods that have identical signatures, but one receives this signature through a common substitution - then we select a “natural” signature over the “substituted” signature.
UPDATE:
What we have in the C # specification (7.5.3):
When a generic method is generated without specifying type arguments, the type inference process tries to print the type arguments for the call. Through type inference, an argument of type int is determined from the argument to the method. Type inference occurs as part of the processing time binding of a method call and takes place before step of allowing call overload resolution.
When a particular group of methods is specified in a method call, and type arguments are not specified as part of the method call, type inference is applied to each generic method in the method group. If the type inference succeeds, then the inferred type arguments are used to determine the types of the arguments for subsequent overload resolution. If overload resolution selects a generic method as the one being invoked, then the inferred type arguments are used as the actual type arguments for the call. If type inference for a particular method is not performed, this method is not involved in overload resolution.
Therefore, before overload resolution, we have two methods in the method group. One DoWork(int) and the other output is DoWork<int>(int) .
And we will move on to 7.5.3.2 (the best member of the function):
In the case when the sequence of parameter types {P1, P2, ..., PN} and {Q1, Q2, ..., QN} are equivalent (that is, each Pi has an identity transformation to the corresponding Qi), the following rules are tie- breaks are used to determine the best member of a function. 1) If MP is not a general method, and MQ is a general method, then MP is better than MQ.
Sergey Berezovskiy
source share