2012-04-02 21 views
7

I mają następujące prosty kodJak wywołać metodę nadpisania, która ma przeciążenia?

abstract class A 
{ 
    public abstract void Test(Int32 value); 
} 

class B : A 
{ 
    public override void Test(Int32 value) 
    { 
     Console.WriteLine("Int32"); 
    } 

    public void Test(Double value) 
    { 
     Test((Int32)1); 
    } 
} 

Gdy uruchomiony ten kod paska testowego ((Int32) 1) powoduje przepełnienie stosu z uwagi na nieskończonej rekursji. Jedynym możliwym sposobem, aby poprawnie nazwać właściwą metodę (z parametrem liczba całkowita) znalazłem to

(this as A).Test(1); 

Ale to nie jest odpowiedni dla mnie, ponieważ obie metody testowe są publiczne i jestem gotów użytkownicy, aby móc wywołać zarówno metoda?

Odpowiedz

4

Niestety, aby wywołać A::Test(int) przez odniesienie B potrzebne jest pewnego rodzaju rzutowanie. Tak długo, jak kompilator C# widzi odniesienie przez B, wybierze wersję B::Test(double).

Nieco mniej brzydki wersja jest następująca

((A)this).Test(1); 

Inna myśl jest jednak dysponują metodę z inną nazwą, że zarówno w paszy.

class B : A { 
    public override void Test(int i) { 
    TestCore(i); 
    } 
    public void Test(double d) { 
    TestCore(1); 
    } 
    private void TestCore(int i) { 
    // Combined logic here 
    } 
} 
5

rozdzielczości przeciążenia metody w C# nie zawsze zachowują się jak można się spodziewać, ale kod zachowuje się zgodnie ze specyfikacją (pisałem a blog post o tym jakiś czas temu).

W skrócie, kompilator zacząć od znalezienia metod

  • ma taką samą nazwę (w przypadku Test)
  • są zadeklarowane w rodzaju (w przypadku B) lub jednej z jej podstawy typy
  • nie są zadeklarowane z modyfikatora wymuszenia

Należy zauważyć, że ostatni punkt. Jest to faktycznie logiczne, ponieważ metody wirtualne są rozwiązywane w czasie wykonywania, a nie podczas kompilacji.

Na koniec, jeśli typ (w tym przypadku B) ma metodę, która jest kandydatem (co oznacza, że ​​parametry w twoim wywołaniu można niejawnie przekonwertować na typ parametru metody kandydującej), ta metoda zostanie użyta . Twoja nadpisana metoda nie jest nawet częścią procesu decyzyjnego.

Jeśli chcesz wywołać metodę nadpisaną, musisz najpierw rzucić obiekt na jego typ podstawowy.

Powiązane problemy