2010-10-07 11 views
21

Czas na teoretyczne pytanie, które właśnie napotkałem.Częściowe przesłonięcie wirtualnej automatycznej właściwości w klasie dziecka

Poniższy kod jest poprawny i kompiluje:

public class Parent 
{ 
    public virtual object TestProperty { get; set; } 
} 

public class Child : Parent 
{ 
    private string _testValue = "Hello World!"; 

    public override object TestProperty 
    { 
     get { return _testValue; } 
    } 
} 

public class Consumer 
{ 
    Parent p = new Child(); 

    public Consumer(){ p.TestProperty = 3; } 
} 

Moje pytanie brzmi:

Dlaczego C# pozwala mi częściowo zastąpić właściwość TestProperty auto u dziecka, gdy prowadzi to do częściowego nieprzewidywalne zachowanie ? Czy istnieje praktyczna aplikacja?

Mogę ustawić wartość TestProperty za pomocą narzędzia ustawiającego rodzica (sprawdziłem, że generowany jest IL, a program ustawiający nadal ustawia obiekt bazowy w klasie nadrzędnej), chociaż wartość nie jest publicznie dostępna.

+1

Interesujące pytanie! –

+2

Jestem pewien, że istnieje wiele dziwnych rzeczy, które się kompilują i działają, ale nie mają praktycznego zastosowania i potencjalnych brzydkich efektów ubocznych. Młotki budują domy lub rozbijają kciuki w zależności od tego, jak ich używasz :) –

+2

@Dave - Bardzo prawdziwe. Chcę tylko upewnić się, że w tym przypadku rozbijanie kciuków młotkiem nie służy jakimś celom, którego po prostu nie widzę. –

Odpowiedz

12

To zachowanie jest zgodne z właściwościami nieautomatycznie wdrożonymi w języku C#. Zawsze było możliwe przesłonięcie tylko metody get lub set dla właściwości wirtualnej. W związku z tym niemożność wykonania zautomatyzowanej właściwości spowodowałaby niepotrzebną niekonsekwencję.

Na przykład poniższa jest legalne

class A 
{ 
    public virtual int P1 
    { 
     get { return 42; } 
     set { } 
    } 
} 

class B : A 
{ 
    public override int P1 
    { 
     get { return 18; } 
    } 
} 
+0

Wystarczająco fair. Pytanie nie jest więc ograniczone do właściwości automatycznych. Wciąż jednak trochę rozmyte przy praktycznym zastosowaniu. Jeśli deklaruję całą moją własność jako pojedynczą jednostkę, a ta jednostka składa się z kupna i seta ... dlaczego miałbym chcieć nadpisać jedną i pozostawić drugą z potencjalnie mylącym zachowaniem? –

+0

@Justin, Pozycje get i set właściwości są zasadniczo różnymi metodami, więc ma to sens, że można je oddzielnie zmienić. Jeśli chodzi o powód, dla którego chciałbyś, być może, chciałbym dodać dodatkową walidację w ustawieniach lub zachowaniu buforowania w pobierającym, ale zachowaj domyślne zachowanie dla drugiego. Jestem pewna, że ​​istnieje wiele ważnych przypadków użycia dla tego – JaredPar

+1

@JaredPar - Rozumiem, że są to zasadniczo różne metody, ale logicznie te dwie są sprzężone w moim umyśle. Jednakże, jeśli chodzi o projektowanie języka, nie ma potrzeby nadpisywania obu, a jeśli chcesz zachować istniejącą funkcjonalność, po prostu wywołaj metodę return base.TestProperty() ;? (może dlatego nie jestem stworzony do projektowania języków) –

1

Nie ma sens dla seter, chociaż? Jeśli częściowo przesłonisz tylko ustawiacz, może to być przydatne, abyś mógł odpowiedzieć na to zdarzenie, oprócz wywoływania base.TestProperty = value, bez konieczności zawracania sobie głowy również nadpisaniem szablonu.

Powiązane problemy