2013-01-25 16 views
5

Chciałbym wiedzieć, czy jest możliwy dostęp do podstawowej metody wirtualnej za pomocą klasy dziedziczącej (która przesłania metodę).Dostęp do wirtualnej metody klasy Parent z dziedziczenia obiektu klasy Child

Wiem, że to nie jest dobra praktyka, ale chcę to wiedzieć, jeśli jest to technicznie możliwe. Nie stosuję się do takich praktyk, prosząc tylko z ciekawości.

Widziałem kilka podobnych pytań, ale nie znalazłem odpowiedzi, której szukam.

Przykład:

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

Proszę wyjaśnić downvotes. Każdy link do istniejącego podobnego pytania (z zadowalającą odpowiedzią) na stackoverflow jest akceptowalną odpowiedzią. Dzięki.

+0

Odpowiedziałem praktycznie to samo pytanie wczoraj, tutaj; http://stackoverflow.com/questions/14491513/calling-both-base-and-derived-methods/14491581#14491581 –

+0

jawnie wywołaj metodę klasy Parent Print(). Oczywiście, jak zauważyłeś, architektura ta jest próbą odwrócenia zachowania polimorficznego - niezbyt mądra –

+0

@AdityaSihag; to nie działa dla nadpisanych metod. Tylko "nowe", jak na powyższym linku. –

Odpowiedz

4

Zgodnie połączonego z duplikatu ja skomentowałem, można to zrobić z kilku sztuczek, takich jak odbicia:

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

Tego właśnie szukałem. Dziękuję za udostępnienie. –

1

Nie - nie można wywołać metody wirtualnej klasy bazowej - najbardziej pochodna implementacja metody jest wywoływana w takich scenariuszach. W podanym przez Ciebie przykładzie wydrukuje on w obu przypadkach "Print in Child".

+0

-1; tak jest, jak na zduplikowany link zamieszczony powyżej. –

+1

Niezupełnie! tworzenie metody z tym samym podpisem w klasie pochodnej z NOWYM słowem kluczowym polega na zacieniowaniu lub ukryciu metody w klasie bazowej. Oznacza to, że wywołujesz metodę NEW z klasy pochodnej, a nie metodę z klasy bazowej. Spraw, aby twoje oświadczenie o druku miało inną literalność niż twoja NOWA metoda klasy pochodnej i zobacz ją na własne oczy! –

1

Według mnie, najlepiej można zrobić, to:

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

To jest dokładnie mój kod. Gdyby to zadziałało, nie było powodu, dla którego zadawałem pytanie. –

+0

Proszę zauważyć base.Print() w klasie Child Print().Spowoduje to wywołanie wywołania do jej metody drukowania klasy podstawowej. – mihirj

+0

Przepraszam, moje złe. Cóż, wywołanie metody bazowej od dziecka nie jest moją intencją. Zastanawiałem się, czy jest to technicznie możliwe, jeśli nie można wprowadzić żadnych zmian kodu do żadnej z klas. Dzięki za odpowiedź. Doceniam to. –

0

nie wiem kiedy to będzie pomocne. Ale dobrym rozwiązaniem może być przeciążenie lub napisanie fałszywej metody, która wywołuje tylko klasę ojca. Byłoby to wyglądać mniej więcej tak:

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

a następnie w głównym sposobem:

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

Więc to zrobić, co chciał zrobić. W rzeczywistości widziałem tego typu obejście, aby powiedzieć, czy chcesz wywołać metodę bazową, czy nie.

Powiązane problemy