2009-08-26 16 views

risposta

78

Utilizzando i costrutti del linguaggio C#, non è possibile chiamare esplicitamente la funzione di base da di fuori nel campo di applicazione A o B. Se hai davvero bisogno di farlo, allora c'è un difetto nel tuo progetto - cioè quella funzione non dovrebbe essere virtuale per cominciare, o parte della funzione di base dovrebbe essere estratta in una funzione non virtuale separata.

È possibile da all'interno B.X tuttavia chiamare A.X

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

Ma questa è un'altra cosa.

Come indicato da Sasha Truf in this answer, è possibile farlo tramite IL. Probabilmente è anche possibile farlo attraverso la riflessione, come mhand sottolinea nei commenti.

+6

(Hi Solo per la cronaca, qualcuno eliminato il tag 'del stupido trucco che ho aggiunto, e poi qualcuno altrimenti ha cancellato il commento sottolineandolo, facendolo apparire come vorrei/ho bisogno di farlo. Sarebbe utile ricevere notifiche delle modifiche stupide che le persone sembrano voler fare su SO.) – mackenir

+0

Chiamata AX() dall'interno di B è l'unica situazione in cui riesco a vedere che hai bisogno di chiamarlo una volta superato. Supponiamo che tu abbia un metodo di copia con i membri della classe base, quindi esegui l'override per aggiungere funzionalità di copia per i nuovi membri e chiamare base.copy() all'interno in modo che tutto venga copiato. – steviesama

+0

Interessante, avrei pensato che potesse essere realizzato tramite la riflessione? – mhand

6

Non puoi, e non dovresti. Questo è il polimorfismo, quindi ogni oggetto ha il suo modo di fare alcune cose "di base".

7

Puoi farlo, ma non nel punto che hai specificato. Nel contesto di B, è possibile chiamare A.X() chiamando base.X().

4

I konow è la domanda di storia ora. Ma per altri googler: potresti scrivere qualcosa del genere. Ma ciò richiede un cambiamento nella classe base che lo rende inutile con le librerie esterne.

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

Non è possibile farlo con C#, ma è possibile modificare MSIL.

codice IL della vostra principale metodo di:

.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 
} 

Si dovrebbe cambiare codice operativo in L_0008 da callvirt a chiamata

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

E 'impossibile se il metodo viene dichiarato nel classe derivata come overrides. per fare questo, il metodo nella classe derivata deve essere dichiarato come 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

Problemi correlati