Résolution de surcharge des méthodes virtuelles

Considérons le code

public class Base { public virtual int Add(int a,int b) { return a+b; } } public class Derived:Base { public override int Add(int a,int b) { return a+b; } public int Add(float a,float b) { return (Int32)(a + b); } } 

Si je crée une instance de la classe Derived et appelle Add avec des parameters de type int, il appelle la méthode Add avec des parameters float

 Derived obj =new Derived() obj.Add(3,5) // why this is calling Add(float a,float b) 

Pourquoi n’appelle-t-on pas la méthode plus spécifique?

C’est par conception. La section 7.5.3 de la spécification du langage C # stipule:

Par exemple, l’ensemble des candidats à une invocation de méthode n’inclut pas les méthodes marquées avec un remplacement (§7.4) et les méthodes d’une classe de base ne sont pas candidates si une méthode d’une classe dérivée est applicable (§7.6.5.1).

En d’autres termes, étant donné que votre classe Derived a une méthode Add non substituée, la méthode Add de la classe Base (et sa version remplacée dans Derived ) ne sont plus candidates à la résolution de surcharge.

Même si Base.Add(int,int) conviendrait mieux, l’existence de Derived.Add(float,float) signifie que la méthode de la classe de base n’est jamais considérée par le compilateur.

Eric Lippert explique certaines des raisons de cette conception dans cet article de blog .

http://www.yoda.arachsys.com/csharp/teasers-answers.html

lors du choix d’une surcharge, s’il existe des méthodes compatibles déclarées dans une classe dérivée, toutes les signatures déclarées dans la classe de base sont ignorées, même si elles sont écrasées dans la même classe dérivée!