Étant donné le code suivant, existe-t-il un moyen d'appeler la version de classe A de la méthode X?
class A
{
virtual void X() { Console.WriteLine("x"); }
}
class B : A
{
override void X() { Console.WriteLine("y"); }
}
class Program
{
static void Main()
{
A b = new B();
// Call A.X somehow, not B.X...
}
En utilisant les constructions de langage C #, vous ne pouvez pas appeler explicitement la fonction de base depuis en dehors de la portée de A
ou B
. Si vous avez vraiment besoin de le faire, il y a un défaut dans votre conception - c'est-à-dire que cette fonction ne doit pas être virtuelle au départ, ou qu'une partie de la fonction de base doit être extraite vers une fonction non virtuelle distincte.
Vous pouvez de à l'intérieur B.X mais appelez A.X
class B : A
{
override void X() {
base.X();
Console.WriteLine("y");
}
}
Mais c'est autre chose.
Comme le souligne Sasha Truf dans cette réponse , vous pouvez le faire via IL. Vous pouvez probablement aussi l'accomplir par la réflexion, comme le souligne mhand dans les commentaires.
Vous ne pouvez pas le faire en C #, mais vous pouvez modifier MSIL.
Code IL de votre méthode Main:
.method private hidebysig static void Main() cil managed
{
.entrypoint
.maxstack 1
.locals init (
[0] class MsilEditing.A a)
L_0000: nop
L_0001: newobj instance void MsilEditing.B::.ctor()
L_0006: stloc.0
L_0007: ldloc.0
L_0008: callvirt instance void MsilEditing.A::X()
L_000d: nop
L_000e: ret
}
Vous devez changer l'opcode dans L_0008 de callvirt à call
L_0008: call instance void MsilEditing.A::X()
Vous pouvez le faire, mais pas au point que vous avez spécifié. Dans le contexte de B
, vous pouvez appeler A.X()
en appelant base.X()
.
Vous ne pouvez pas, et vous ne devriez pas. C'est à cela que sert le polymorphisme, de sorte que chaque objet a sa propre façon de faire des choses "de base".
Je ne connais pas sa question d'histoire. Mais pour les autres googleurs: vous pourriez écrire quelque chose comme ça. Mais cela nécessite un changement de classe de base ce qui la rend inutile avec les bibliothèques externes.
class A
{
void protoX() { Console.WriteLine("x"); }
virtual void X() { protoX(); }
}
class B : A
{
override void X() { Console.WriteLine("y"); }
}
class Program
{
static void Main()
{
A b = new B();
// Call A.X somehow, not B.X...
b.protoX();
}
C'est impossible si la méthode est déclarée dans la classe dérivée comme overrides
. pour ce faire, la méthode de la classe dérivée doit être déclarée comme new
:
public class Base {
public virtual string X() {
return "Base";
}
}
public class Derived1 : Base
{
public new string X()
{
return "Derived 1";
}
}
public class Derived2 : Base
{
public override string X() {
return "Derived 2";
}
}
Derived1 a = new Derived1();
Base b = new Derived1();
Base c = new Derived2();
a.X(); // returns Derived 1
b.X(); // returns Base
c.X(); // returns Derived 2