In accordance with the rules of clause 7.5.3.2, the C # 4 specification ("Better member function").
First (well, given that both methods are applicable), we need to check the conversion from argument types to parameter types. In this case, it is quite simple, because there is only one argument. Neither converting the argument type to the parameter type is โbetterโ because both are converted from ConcreteA to IfaceA . Therefore, he proceeds to the next set of criteria, including this:
Otherwise, if MP has more specific parameters than MQ, then MP is better than MQ. Let {R1, R2, ..., RN} and {S1, S2, ..., SN} be unreasonable and unexpanded parameters of the parameters MP and MQ. MPs parameter types are more specific than MQ if for each parameter RX is not less specific than SX, and for at least one parameter, RX is more specific than SX: specific than SX:
- A type parameter is less specific than a non-type parameter.
- ...
Thus, although the conversion is equally good, overloading with IfaceA directly (and not through delegates) is considered "better" because an IfaceA type IfaceA more specific than a T type parameter.
It is not possible to force the compiler to warn about this behavior - this is just a normal overload resolution.
Jon skeet
source share