Le proprietà protette sono malvagie? [duplicare]

1

Parte introduttiva del codice:

class BaseClass
{
    protected Foo MyFoo { get; }
}

class ChildClass : BaseClass
{
    void SomeMethod()
    {
        MyFoo.DoStuff();
        //Here, I have no idea that MyFoo is not defined in this class,
        //but rather in the base class.
    }
}

Il problema / dibattito è che devi sapere o controllare manualmente dove è definito MyFoo. E stai meglio usando due campi privati, uno nella classe base, nella classe child.

Nel nostro caso, la maggior parte delle volte queste proprietà provengono dall'iniezione di dipendenza e sono disponibili nel costruttore di entrambi classi. Quindi è davvero semplice mapparli a proprietà private da quel costruttore, invece di ereditarlo dalla classe base, che è anche meno chiaro.

C'è una buona pratica che mi manca? Qual è la tua esperienza lì?

Domanda di fondo: le proprietà protette sono solo una cattiva abitudine e dovrei sempre cercare i campi privati?

Questo andrà contro di me durante i test unitari?

È considerato un codice pulito / sporco?

    
posta Gil Sand 13.11.2017 - 15:28
fonte

3 risposte

22

Non penso che duplicare la proprietà nella sottoclasse (e nel suo costruttore) sia davvero un'alternativa migliore. Per le proprietà di lettura / scrittura effettive, che non possono nemmeno fornire la stessa funzionalità e per le proprietà iniettate di sola lettura come nel tuo caso (probabilmente un tipo di servizio), non importa molto dove è definito. Inoltre, il tuo IDE può mostrarti facilmente.

In sostanza, il modo di guardarlo è questo:

  • I campi protetti fanno parte dell'API classe per la sottoclasse, proprio come i metodi.
  • I campi protetti che contengono effettivamente dati mutabili possono sicuramente risultare in un codice difficile da capire, ma possono quindi contenere metodi protetti quando vengono sovrascritti in sottoclassi ma chiamati nella superclasse.
  • Il problema qui non è campi o metodi protetti, il problema è la sottoclasse. Dovrebbe essere usato con attenzione e con parsimonia.
  • Una regola empirica che ho appena inventato: la superclasse dovrebbe essere molto piccola e semplice o la sottoclasse. E le gerarchie di ereditarietà sono pessime.
risposta data 13.11.2017 - 15:53
fonte
12

you have to either know or check manually where MyFoo is defined

Ma come è specifico per proprietà protette ? Lo stesso vale per i metodi e davvero qualsiasi membro pubblico. Una grande ragione per l'eredità è evitare di dover ripetere la stessa cosa per ogni tipo concreto. Quindi puoi avere un tipo di base comune che contiene il comportamento di base e le definizioni di archiviazione di base.

Una proprietà o un campo in fase di protezione ti dice solo che questo è un dettaglio di implementazione interno che è probabile essere rilevante per le sottoclassi. In un certo senso, questo in realtà ti dice di più che avere proprietà private completamente disconnesse su ogni livello.

E il compilatore sa già dove è definito e come è accessibile. E i buoni editor ti diranno che in fase di progettazione, quindi non c'è davvero bisogno di "controllare manualmente". Inoltre, quando erediti un tipo, mi aspetto che tu sia a tuo agio con la sua interfaccia, quindi sai che ci sono membri protetti che puoi usare.

In our case these properties come from dependency injection

Questa potrebbe essere solo la mia opinione, ma userei sempre readonly campi per le dipendenze, non per le proprietà.

So it's really easy to just map them to private properties from that constructor

Certo, potresti avere un campo privato su ogni livello della tua gerarchia di tipi. Ma questo duplicherà anche l'utilizzo della memoria di cui hai bisogno per tenere traccia di quelli. E se per un momento ignori il fatto che si tratta di dipendenze immutabili iniettate nel costruttore, una classe base che non è in grado di modificare il valore per le sue sottoclassi potrebbe anche introdurre problemi.

Are protected properties just a bad habit, and should I always go for private fields instead ?

Ci sono due domande qui: Proprietà vs. campo e protected rispetto a private . Per rispondere a quest'ultimo: utilizzare ciò che ha senso in un senso di incapsulamento. Se il tuo tipo base ha effettive API interne che le sottoclassi potrebbero utilizzare, queste dovrebbero essere protette. Ma non dovresti semplicemente rendere qualsiasi dipendenza protetta solo nel caso .

    
risposta data 13.11.2017 - 16:34
fonte
6

Are protected properties evil?

No. Le proprietà protette sono smelly , ma non evil . Cioè, dovrebbero farti pensare "sto modellando questo correttamente?" Si pensa a una proprietà come parte della superficie pubblica di un modello e a un campo come a un dettaglio di implementazione privata di un modello. Poiché "protetto" significa semplicemente "un dettaglio di implementazione privata di questa gerarchia", ci si aspetta campi protetti piuttosto che proprietà protette.

Detto questo, le proprietà protette non sono sbagliate ; sono solo un segno che forse hai bisogno di pensare al tuo design un po 'più difficile.

Here, I have no idea that MyFoo is not defined in this class, but rather in the base class.

Naturalmente lo sai. Puoi leggere il codice sorgente della classe e vedere chiaramente che non esiste una tale proprietà. E puoi "andare alla definizione" e andare al codice sorgente della proprietà.

The problem/debate is that you have to either know or check manually where MyFoo is defined.

No, non lo fai. Perché pensi di dover sapere dove è definito?

And you're better off using 2 private fields, one in the base class, on in the child class.

No, non sono affatto d'accordo. Forse starai meglio usando un campo protetto nella classe base.

Are protected properties just a bad habit, and should I always go for private fields instead ?

Se ti ritrovi a scrivere molte proprietà protette, ti chiederei se sono effettivamente meglio modellate come campi protetti. Ricorda, una proprietà dovrebbe modellare una proprietà della cosa modellata . Se stai scrivendo una classe Car , le sue proprietà dovrebbero essere le proprietà di una macchina . Quali sono entrambe le proprietà di una macchina e anche i dettagli di implementazione della gerarchia di automobili ? Non riesco a pensare a qualcosa che sia entrambe quelle cose, e quindi forse non dovrebbero esserci proprietà protette.

    
risposta data 13.11.2017 - 22:36
fonte