2010-10-07 9 views
21

Tempo per una domanda teorica che ho appena incontrato.Sovraccarico parziale di una proprietà automatica virtuale in una classe figlio

Il seguente codice è valido e compila:

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

La mia domanda è:

Perché C# mi permette di ignorare in parte la proprietà TestProperty auto in un bambino quando si porta ad un comportamento parzialmente imprevedibile ? Esiste un'applicazione pratica?

Sono autorizzato a impostare il valore di TestProperty utilizzando il setter del genitore (ho controllato che l'IL sia stato generato e il setter sta ancora impostando l'oggetto di supporto nella classe genitore) anche se il valore non è accessibile al pubblico.

+1

Interessante domanda! –

+2

Sono sicuro che ci sono molte cose strane come questa che verranno compilate e funzionanti, ma non hanno alcuna applicazione pratica e potenziali effetti collaterali brutti. I martelli costruiscono case o fanno schifo a seconda di come li usi :) –

+2

@Dave - Molto vero. Voglio solo assicurarmi che, in questo caso, spaccandomi i pollici con un martello non abbia uno scopo che non vedo. –

risposta

12

Questo comportamento è coerente con le proprietà non implementate automaticamente in C#. È sempre stato possibile sovrascrivere solo un metodo get o set per una proprietà virtuale. Quindi rendere impossibile l'uso di una proprietà auto-implementata creerebbe un'incoerenza inutile.

Ad esempio, il seguente è legale

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

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

Abbastanza giusto. La domanda, quindi, non è limitata alle proprietà automatiche. Ancora un po 'sfocato però sull'applicazione pratica. Se dichiaro la mia intera proprietà come una singola unità e quell'unità è composta da un get e un set ... perché dovrei ignorarne uno e lasciare l'altro con un comportamento potenzialmente confuso? –

+0

@Justin, le parti get e set di una proprietà sono metodi fondamentalmente diversi, quindi ha senso che possano essere sostituiti indipendentemente. Per quanto riguarda il motivo per cui si vorrebbe forse io voglio aggiungere una validazione extra nel setter o nel comportamento di caching nel getter ma mantenere il comportamento predefinito per l'altro. Sono sicuro che ci sono un certo numero di casi d'uso validi per fare questo – JaredPar

+1

@JaredPar - Capisco che sono metodi fondamentalmente diversi, ma logicamente i due sono accoppiati nella mia mente. In termini di progettazione della lingua, tuttavia, perché non richiedere l'override di entrambi e quindi se si desidera mantenere la funzionalità esistente, è sufficiente chiamare return base.TestProperty() ;? (forse questo è il motivo per cui non sono tagliato fuori per progettare le lingue) –

1

non ha senso per un setter, però? Se si sostituisce solo parzialmente il setter, ciò potrebbe essere utile per poter rispondere a tale evento, oltre a chiamare base.TestProperty = value, senza doversi preoccupare anche di ignorare un interruttore di accensione del getter.