2013-01-25 11 views
5

Vorrei sapere se è possibile accedere al metodo virtuale di base utilizzando un oggetto di classe ereditante (che sovrascrive il metodo).Accesso al metodo virtuale della classe padre dall'assegnazione di oggetto classe figlio

So che questa non è una buona pratica, ma la ragione per cui voglio sapere questo è se è tecnicamente possibile. Non seguo questa pratica, chiedendo solo per curiosità.

Ho visto alcune domande simili ma non ho ottenuto la risposta che sto cercando.

Esempio:

public class Parent 
{ 
    public virtual void Print() 
    { 
     Console.WriteLine("Print in Parent"); 
    } 
} 

public class Child : Parent 
{ 
    public override void Print() 
    { 
     Console.WriteLine("Print in Child"); 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     Child c = new Child(); 
     //or Parent child = new Child(); 
     child.Print(); //Calls Child class method 
     ((Parent)c).Print(); //Want Parent class method call 
    } 
} 

Si prega di spiegare downvotes. Qualsiasi risposta a una domanda simile esistente (con risposta soddisfacente) su stackoverflow è una risposta accettabile. Grazie.

+0

ho risposto praticamente la stessa domanda ieri, qui; http://stackoverflow.com/questions/14491513/calling-both-base-and-derived-methods/14491581#14491581 –

+0

chiama in modo esplicito il metodo Print() della classe padre. Ovviamente, come hai notato, questa architettura è nel tentativo di invertire il comportamento polimorfico - non saggio –

+0

@AdityaSihag; non funziona per i metodi sovrascritti. Solo 'nuovo', come da link sopra. –

risposta

4

Come per il duplicato collegato ho commentato con, è possibile farlo con alcuni trucchi di riflessione in quanto tali:

static void Main(string[] args) 
{ 
    Child child = new Child(); 
    Action parentPrint = (Action)Activator.CreateInstance(typeof(Action), child, typeof(Parent).GetMethod("Print").MethodHandle.GetFunctionPointer()); 

    parentPrint.Invoke(); 
} 
+0

Questo è esattamente quello che stavo cercando. Grazie per la condivisione. –

1

No: non è possibile richiamare il metodo Virtuale della classe Base: l'implementazione più derivata del metodo viene invocata in tali scenari. Nell'esempio da voi fornito, verrà stampato "Print in Child" in entrambi i casi.

+0

-1; sì lo è, come per il link duplicato pubblicato sopra. –

+1

Non proprio! creando un metodo con la stessa firma nella classe derivata con la parola chiave NEW si nasconde o si nasconde il metodo nella classe base. Ciò significa che stai invocando il nuovo metodo dalla classe derivata e non il metodo dalla classe base. Fai in modo che la tua dichiarazione di stampa abbia un valore letterale diverso da quello del tuo nuovo metodo di classe derivata e guardalo tu stesso! –

1

Secondo me, il meglio che puoi fare è:

public class Parent 
{ 
    public virtual void Print() 
    { 
     Console.WriteLine("Print in Parent"); 
    } 
} 

public class Child : Parent 
{ 
    public override void Print() 
    { 
     base.Print(); 
     Console.WriteLine("Print in Child"); 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     Child c = new Child(); 
     //or Parent child = new Child(); 
     child.Print(); //Calls Child class method 
     ((Parent)c).Print(); //Want Parent class method call 
    } 
} 
+0

Questo è esattamente il mio codice. Se ciò avrebbe funzionato, non c'era motivo per cui stavo facendo una domanda. –

+0

Si prega di notare base.Stampa() chiamata in Classe figlio Stampa().Ciò attiverà una chiamata al suo metodo di stampa di classe base. – mihirj

+0

Mi dispiace, mio ​​male. Beh, non è mia intenzione chiamare il metodo base dal bambino. Mi stavo chiedendo se fosse tecnicamente possibile se non è possibile apportare modifiche al codice a nessuna delle classi. Grazie per la risposta però. Lo apprezzo. –

0

non saprei quando questo sarebbe utile. Ma una soluzione decente potrebbe essere quella di sovraccaricare o scrivere un metodo fittizio che chiama solo la classe padre. Sarebbe simile a questa:

public class Child : Parent 
{ 
    public void Print(bool onlyCallFather) 
    { 
    if(onlyCallFather) 
     base.Print(); 
    else 
     Print(); 
    } 
} 

E poi nel metodo principale:

class Program 
{ 
    static void Main(string[] args) 
    { 
     Child c = new Child(); 
     child.Print(false); //Calls Child class method 
     child.Print(true); //Calls only the one at father 
    } 
} 

Quindi sarebbe fare quello che voleva fare. In realtà ho visto questo tipo di soluzione per dire se si desidera chiamare o meno il metodo base.

Problemi correlati