Se qualcosa si comporterebbe come una proprietà di lettura-scrittura, dovrebbe generalmente essere implementata usando una proprietà di lettura-scrittura. D'altra parte, il fatto che il valore di una proprietà possa essere cambiato non significa che si comporterà come una proprietà di lettura-scrittura. Suggerirei che, in generale, qualcosa dovrebbe essere implementato come proprietà di lettura-scrittura solo se agisce come una proprietà "pulita" (descritta di seguito), anche se noterei che molte classi in .net usano proprietà di lettura-scrittura in modi che non sono conforme a ciò che suggerisco. Direi che in molti casi ciò deriva dalla pressione del tempo per implementare il framework prima che il pieno background filosofico fosse completamente elaborato.
Considererei una proprietà read-write come pulita se:
- La lettura non avrà mai alcun effetto collaterale e produrrà sempre lo stesso valore in assenza di una chiamata di metodo o di scrivere su quella proprietà.
- Leggendolo e poi riscrivendo il valore letto non avrà alcun effetto.
- Una lettura che segue una scrittura senza una chiamata al metodo intermedio produrrà sempre il valore scritto.
- Scrivere la proprietà più di una volta senza chiamate di metodo intermedio avrà lo stesso effetto di eseguire solo l'ultima scrittura.
- In assenza di chiamate al metodo intermedio, l'effetto di impostare una proprietà pulita su X e quindi di impostare un'altra proprietà su Y sarà lo stesso di impostare l'altra proprietà su Y e quindi impostare quella pulita su X.
Si noti che è perfettamente ammissibile che una scrittura in una proprietà "pulita" influenzi lo stato di altre proprietà di sola lettura. L'effetto dell'impostazione di più proprietà dovrebbe dipendere dai valori scritti, ma non dalla sequenza in cui si verificano le scritture. Se myRect
è inizializzato su (X = 1, Y = 2, Larghezza = 3, Altezza = 4), l'effetto di MyRect.X=2; MyRect.Top = MyRect.Right;
dovrebbe essere uguale a MyRect.X = 2; MyRect.Top = 5;
o MyRect.Top = 5; MyRect.X = 2;
, anche se non sarebbe essere uguale a MyRect.Top = MyRect.Right; MyRect.X = 2;
.
Molte classi .net usano le proprietà in modi che sono da queste definizioni "sporche". Utilizzando queste definizioni, ad esempio, StringBuilder. Length
dovrebbe essere probabilmente una proprietà di sola lettura, ma Text
potrebbe probabilmente essere una proprietà di lettura-scrittura (la lettura di Text
sarebbe equivalente a ToString()
, mentre la scrittura sarebbe equivale a eliminarlo e a fare Append
).
Ci sono varietà di situazioni in cui si può essere in grado di modificare le proprietà di un oggetto, ma non dovrebbero essere considerate "pulite proprietà di lettura-scrittura". Tra questi:
- Un rettangolo che memorizza (X, Y, Larghezza, Altezza) e li espone come proprietà di lettura-scrittura potrebbe avere una proprietà 'Giusta', ma il tentativo di impostarlo influenzerebbe uno degli altri.
- Un oggetto può contenere un riferimento a un oggetto "IDisposable" e ci si può aspettare che venga chiamato "Dispose" su di esso quando non è più necessario. Un metodo 'SetXXAndTakeOwnership ()' offrirebbe semantica più chiara (chiamata 'Dispose' il vecchio oggetto prima di impostare la proprietà) offrirebbe semantica molto più chiara di una proprietà di lettura-scrittura.
- Alcuni oggetti possono avere proprietà che possono essere impostate solo su determinate combinazioni di valori; avere un metodo per impostare tutte queste proprietà in una volta può essere molto più bello che dover impostare le proprietà singolarmente e preoccuparsi del sequenziamento. 'ProgressBar' è particolarmente icky in questo senso, dal momento che le sue proprietà devono essere scritte in un ordine che dipende da vecchi e nuovi valori; se un 'ProgressBar' sta attualmente indicando 7/9 fatto, cambiandolo a 3/5 è necessario scrivere 'Valore' prima di 'Massimo', ma impostandolo su 14/19 è necessario scrivere prima di aggiornare 'Massimo'. Un metodo 'SetFraction' che accettava i parametri sia per il valore sia per il massimo, e aggiornato contemporaneamente, sarebbe stato molto meglio.
- Alcune proprietà come il tempo rimanente su un timer possono cambiare tra il momento in cui sono scritte e il tempo di lettura. Tali cose possono essere perfettamente fini come proprietà di sola lettura (leggerle richiederebbe del tempo, e l'atto di prendere tempo potrebbe influenzare le letture future, ma tale effetto collaterale non sarebbe diverso da qualsiasi altro codice che il sistema potrebbe eseguire) ma violerebbe la regola che una proprietà pulita dovrebbe restituire l'ultimo valore letto.
Se una di queste condizioni (o una delle tante altre - l'elenco è difficilmente esauriente) si applica, usa un metodo SetXX
piuttosto che una proprietà read-write.