Uso corretto della proprietà vs campo vs funzione in C #

3

Sono stato infastidito da questa riga di codice che ho scritto e sono stato un po 'confuso in quello che dovrebbe essere scritto.

class SomeClass
{
    IBeneficiary _latestBeneficiary => new Beneficiary(Iban, Name);
}

Nel contesto, il campo rappresenta l'ultima versione di un oggetto beneficiario che sta per essere creato, e voglio che questa variabile rappresenti la sua ultima versione possibile considerando qualunque cosa si trovi all'interno di quelle proprietà pubbliche.

Ecco le mie ipotesi e i miei pensieri, sto pensando che ci sia qualcosa di sbagliato lì altrimenti non avrei un problema.

Quindi, chiaramente, questo è un campo. È un campo perché è una variabile privata che tengo nella mia classe, e per riconoscerla, aggiungo un trattino basso come prefisso.

Questo campo restituisce sempre l'ultimo IBeneficiary possibile considerando Iban e Nome (irrilevante qui). Queste proprietà sono pubbliche e classiche MyProperty SomeProperty { get; set; } definite nella classe.

Ho definito un campo con un getter di proprietà, il => . Ciò è fonte di confusione perché non è il comportamento previsto di un campo restituire sempre qualcosa di nuovo. O è?

Credo che questo dovrebbe essere una funzione, qualcosa come

IBeneficiary CreateLatestBeneficiary (MyProperty param1, MyOtherProperty param2)
{ 
      return new Beneficiary(param1, param2);
} 

O anche nominarlo GetLatestBeneficiary , ma in entrambi i casi questo sembra un vero getter, quindi preferirei avere una proprietà con un solo getter, che fa esattamente questo, come il seguente. Giusto?

IBeneficiary LatestBeneficiary
{
   get
   {
       return new Beneficiary(Iban, Name);
   }
}

Ma una proprietà privata è praticamente un campo. Non è vero?

E con questo in mente torniamo al punto di partenza, usando un campo.

Mi sento come da qualche parte lì dentro, una delle mie affermazioni è sbagliata.

Le proprietà private sono a posto? O è una proprietà per definizione qualcosa di pubblico, con almeno un getter? O va bene che un campo non sia una semplice vecchia variabile?

In definitiva, come scriveresti questa riga di codice da solo?

    
posta Gil Sand 23.01.2017 - 20:28
fonte

2 risposte

7

So, clearly, this is a field. It's a field because it is a private variable I'm keeping inside my class, and to recognize it, I add an underscore as a prefix.

Questo non è corretto. Non è un campo; è una proprietà. E quella proprietà è solo zucchero sintattico per un metodo, che il compilatore crea per te. In questo caso quel metodo sarebbe IBeneficiary get__latestBeneficiary() => ...

Solo perché è privato, non lo rende un campo. un campo è una variabile, non un metodo.

Or even name it GetLatestBeneficiary, but in both cases this looks and feels like a really simple getter, so I'd rather have a property with a single getter, that does exactly this, like the following. Right?

Il codice:

IBeneficiary LatestBeneficiary
{
   get
   {
       return new Beneficiary(Iban, Name);
   }
}

è semanticamente identico a:

IBeneficiary _latestBeneficiary => new Beneficiary(Iban, Name);

L'espressione sintassi del corpo della seconda versione è solo un modo più compatto di esprimere quel getter.

I feel like this then should be a function

Tenderei ad essere d'accordo. Anche se si tratta di una proprietà di sola lettura privata, è ancora una proprietà di sola lettura (ad esempio, getter). Portano il bagaglio delle aspettative: la maggior parte degli sviluppatori si aspetta che le proprietà di sola lettura restituiscano lo stesso valore ogni volta (specialmente se lo stato del resto dell'oggetto non è cambiato). Quindi, seguendo il principio del minimo stupore, dovresti evitare di usare le proprietà in questo modo.

Quindi rendi un metodo:

IBeneficiary CreateLatestBeneficiary() => new Beneficiary(Iban, Name);
    
risposta data 23.01.2017 - 22:52
fonte
1
This is confusing because it's not the expected behaviour of a field to always return something new. Or is it?

Sì, è abbastanza confuso. Mi aspetto che un getter restituisca il beneficiario che è stato creato di recente ("ultimo") prima che la funzione fosse chiamata - Vorrei non aspettarsi di crearne uno immediatamente e poi tornare il nuovo beneficiario.

Penso che la tua funzione CreateLatestBeneficiary sia il modo migliore per fare in modo che il nome renda molto chiaro che una nuova cosa esisterà come conseguenza della chiamata alla funzione . Probabilmente lo rinominerò in GenerateNewBeneficiary , ma questa è più la mia preferenza personale di ogni altra cosa.

    
risposta data 23.01.2017 - 20:45
fonte

Leggi altre domande sui tag