2009-08-26 7 views

Répondre

78

En utilisant les constructions de langage C#, vous ne pouvez pas appeler explicitement la fonction de base de l'extérieur la portée de A ou B. Si vous avez vraiment besoin de faire cela, il y a une faille dans votre conception, c'est-à-dire que cette fonction ne doit pas être virtuelle pour commencer, ou qu'une partie de la fonction de base doit être extraite vers une fonction non virtuelle distincte.

Vous pouvez à partir de l'intérieur B.X cependant appeler A.X

class B : A 
{ 
    override void X() { 
    base.X(); 
    Console.WriteLine("y"); 
    } 
} 

Mais c'est autre chose. Comme Sasha Truf fait remarquer dans this answer, vous pouvez le faire par IL. Vous pouvez probablement aussi l'accomplir par réflexion, comme le souligne mhand dans les commentaires.

+6

(Salut Juste pour mémoire, quelqu'un supprimé l'étiquette du « truc stupide que j'ajouté, puis quelqu'un Sinon, j'ai supprimé le commentaire en le faisant remarquer, ce qui me donne l'impression que je veux vraiment le faire.) Il est utile d'être averti des modifications stupides que les gens semblent vouloir faire.) – mackenir

+0

Appeler AX() depuis l'intérieur B est la seule situation que je peux même vous voir avoir besoin de l'appeler une fois dépassé. Supposons que vous ayez une méthode de copie avec les membres de la classe de base, puis remplacez-la pour ajouter une fonctionnalité de copie pour les nouveaux membres et appelez base.copy() à l'intérieur pour que tout soit copié. – steviesama

+0

Intéressant, j'aurais pensé que cela pourrait se faire par réflexion? – mhand

6

Vous ne pouvez pas, et vous ne devriez pas. C'est ce que le polymorphisme est pour, de sorte que chaque objet a sa propre façon de faire des choses "de base".

7

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().

4

Je sais que c'est une question d'histoire maintenant. Mais pour les autres googleurs: vous pourriez écrire quelque chose comme ça. Mais cela nécessite un changement dans la classe de base ce qui le 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(); 


    } 
10

Vous ne pouvez pas le faire en C#, mais vous pouvez modifier MSIL.

code IL de votre principale méthode:

.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 opcode dans L_0008 de callvirt à appel

L_0008: call instance void MsilEditing.A::X() 
2

Il est impossible si la méthode est déclarée dans le classe dérivée comme overrides. pour ce faire, la méthode dans 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 

See fiddle here

Questions connexes