Désolé, mais vous vous trompez complètement; cela irait à l'encontre du point entier des méthodes virtuelles. Si someObject
est un A
, A.MyMethod
sera appelé. Si someObject
est B
alors B.MyMethod
sera invoqué. Si someObject
est un BaseClass
et non une instance d'un type dérivé de BaseClass
alors BaseClass.MyMethod
sera appelé.
Utilisons exemple préféré de tout le monde:
class Animal {
public virtual void Speak() {
Console.WriteLine("i can haz cheezburger?");
}
}
class Feeder {
public void Feed(Animal animal) { animal.Speak(); }
}
class Cat : Animal {
public override void Speak() { Console.WriteLine("Meow!"); }
}
class Dog : Animal {
public override void Speak() { Console.WriteLine("Woof!"); }
}
Puis:
Animal a = new Animal();
Animal c = new Cat();
Animal d = new Dog();
Feeder f = new Feeder();
f.Feed(a);
f.Feed(c);
f.Feed(d);
Ce imprimera:
i can haz cheezburger?
Meow!
Woof!
Encore une fois, cela est tout le point de méthodes virtuelles.
En outre, nous pouvons aller à la spécification. De 10.6.3 (Méthodes virtuelles)
Dans un appel de méthode virtuelle, le type run-time de l'instance pour laquelle cette invocation a lieu détermine la mise en œuvre de la méthode actuelle d'invoquer.
(En gras et en italique dans l'original.)
En termes précis, lorsqu'une méthode nommée N
est invoqué avec une liste d'arguments A
sur une instance avec un type de compilation C
et un type d'exécution R
(où R
est soit C
ou une classe dérivée de C
), l'appel est traité comme suit:
• Premièrement, la résolution de surcharge est appliqué à C
, N
et A
, pour sélectionner une méthode M
spécifique de l'ensemble des méthodes déclarées dans et héritée par C
Ceci est décrit au § 7.5.5.1.
• Ensuite, si M
est une méthode non virtuelle, M
est appelée.
• Sinon, M
est une méthode virtuelle, et la mise en œuvre la plus dérivée de M
par rapport à R est invoquée.
(Bolding pas dans l'original.)
, nous avons besoin ensuite la définition de "la mise en œuvre la plus dérivée de M
." Cette définition est récursive agréable:
La mise en œuvre la plus dérivée d'une méthode virtuelle M
par rapport à une classe R
est déterminée comme suit:
• Si R
contient la déclaration virtuelle introduction de M
, cette est l'implémentation la plus dérivée de M
.
• Sinon, si R
contient un remplacement de M
, il s'agit de l'implémentation la plus dérivée de M
.
• Dans le cas contraire, la mise en œuvre la plus dérivée de M
par rapport à R
est la même que la mise en œuvre la plus dérivée de M
par rapport à la classe de base directe de R
.
Ainsi, dans notre exemple ci-dessus avec Cat : Animal
et Dog : Animal
, lorsque le paramètre a
-Feeder.Feed(Animal)
est une instance de Cat
alors Cat.Speak
est la mise en œuvre la plus dérivée. C'est pourquoi nous verrons "Meow!
" et non "i can haz cheezburger?
"
C'est une odeur de code. – Will
Quel est le type de l'objet ACTUAL que vous transmettez au constructeur AnotherObject? En d'autres termes, quelle est la nouvelle déclaration? Parce que ce que vous décrivez ne peut arriver que si vous créez une BaseClass au lieu d'un A ou un B. – Nick
Je pense que le fait que c'est une odeur de code est évident pour David sinon la question n'aurait pas été postée et le code malodorant aurait été été utilisé à la place. – Greg