2010-09-23 18 views
5

Nie rozumiem następującego zjawiska, czy ktoś mógłby mi wyjaśnić, proszę, co zrobiłem źle?Dziedziczenie i właściwości statyczne

public class BaseClass 
{ 
    public BaseClass() 
    { 
     BaseClass.Instance = this; 
    } 

    public static BaseClass Instance 
    { 
     get; 
     private set; 
    } 
} 

public class SubClassA : BaseClass 
{ 
    public SubClassA() 
     : base() 
    { } 
} 

public class SubClassB : BaseClass 
{ 
    public SubClassB() 
     : base() 
    { } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     SubClassA a = new SubClassA(); 
     SubClassB b = new SubClassB(); 

     Console.WriteLine(SubClassA.Instance.GetType()); 
     Console.WriteLine(SubClassB.Instance.GetType()); 

     Console.Read(); 
    } 
} 

Jak zrozumiałem, kompilator powinien wygenerować nowy typ poprzez dziedziczenie, że SubClassA i SubClassB są naprawdę własne typy z własnych zmiennych statycznych. Ale wydaje się, że statyczna część klasy nie jest dziedziczona, ale odnosi się do niej - co mam źle?

Odpowiedz

10

Dziedziczenie w .NET działa tylko na podstawie instancji. Metody statyczne są definiowane na poziomie typu, a nie na poziomie instancji. Dlatego nadpisywanie nie działa z użyciem statycznych metod/właściwości/zdarzeń ...

Metody statyczne są przechowywane tylko raz w pamięci. Nie ma wirtualnej tabeli itp., Która jest dla nich tworzona.

Jeśli wywołasz metodę instancji w .NET, zawsze nadajesz jej bieżącą instancję. Jest to ukryte w środowisku wykonawczym .NET, ale tak się dzieje. Każda metoda instancji ma jako pierwszy argument wskaźnik (odwołanie) do obiektu, na którym uruchamiana jest metoda. Nie dzieje się tak w przypadku metod statycznych (ponieważ są one zdefiniowane na poziomie typu). W jaki sposób kompilator powinien wybrać metodę wywołania?

+0

ja nie rozumiem dlaczego dziedziczenia działa tylko w przypadkach, ale muszę się z tym pogodzić. Dziękuję za te informacje. –

+0

To samo zachowanie zostało zaimplementowane w PHP i Delphi –

+0

@ VladladlavRastrusny: Nie wiem, jak to jest w 2010 roku. Ale teraz w 2016 roku są 'self ::' i 'static ::' w PHP. –

13

Jest tylko jedna nieruchoma właściwość Instance i jest zdefiniowana w BaseClass, która jest również jedynym typem, który może ją zmienić (ponieważ zbiór to private).

Co się dzieje, że Twoje podklasy SubClassA i SubClassB wywołują konstruktora BaseClass w swoich własnych konstruktorach. Ten konstruktor ustawia Instance na zainicjowaną instancję BaseClass.

Ostatnią taką instancją w przykładowym kodzie jest instancja o numerze SubClassB; w związku z tym właściwość ta jest ustawiana na tę instancję przed uzyskaniem połączenia z numerem Console.WriteLine.

Można odwrócić konstrukcję obiektów SubClassA i SubClassB, a zamiast tego zobaczysz Instance ustawione na instancję SubClassA.

+0

+1 za wyjaśnienie, dlaczego pisze SubClassB dwa razy –