La domanda
La domanda è
So why public fields considered evil due to the encapsulation violation while auto-implemented properties are so great?
La risposta a questa domanda è trattata in uno dei punti tecnici che hai notato
Changing a variable to a property is a breaking change
Se pubblichi qualsiasi classe per chiunque (anche per il tuo futuro io), sei tenuto a mantenere questa interfaccia o rompere una quantità arbitraria di codice che dipende da esso. Per sempre.
L'incapsulamento risolve questo problema fornendo (o meglio, descrivendo) un modo per essere certi di poter apportare modifiche all'implementazione in futuro senza violare alcun codice al di fuori della classe. Cioè, l'utilizzo di campi pubblici ti lega a loro indefinitamente, mentre le proprietà generate automaticamente hanno la possibilità di cambiare in futuro senza rompere il codice chiamante.
Vorrei sottolineare che trasformare un campo in una proprietà non è un cambiamento irrisolto in tutti i linguaggi di programmazione, ma è in C #.
Encapsulation
Nella domanda è implicito un altro che vorrei discutere sul fatto che le proprietà possano fornire o meno l'incapsulamento.
Wikipedia definisce l'incapsulamento come due concetti correlati ma separati:
La domanda afferma che
[properties are] fields which can be changed from any class, and that, as far as I know, violates encapsulation.
Rifiuto questa affermazione basata su entrambe le definizioni di Wiki. Consentitemi di dare uno scenario di straw man e poi di porre alcune domande su di esso per indagare.
Ho creato una classe chiamata Temperatura. Ha proprietà pubbliche per ottenere e impostare la sua temperatura in gradi Celsius, Fahrenheit e Kelvin. Farà qualsiasi conversione tra loro semplicemente scrivendone uno rispetto a un altro.
Domanda 1: Come viene utilizzata la temperatura?
-
Leggere e / o scrivere direttamente le proprietà, secondo la descrizione dell'interfaccia di cui sopra
-
Lettura e / o scrittura di alcuni stati interni che non fanno parte dell'interfaccia pubblica specificata sopra
-
Qualche altra risposta di cui non sono a conoscenza
Domanda 2: Come viene implementata la temperatura?
-
Ogni proprietà ha una variabile nascosta di supporto, con ogni setter che aggiorna tutte e tre le variabili di supporto. I getter fanno solo eco alla variabile.
-
C'è una variabile di supporto (in Rankines) aggiornata da tutti e tre i setter. Ogni getter si converte da Rankines all'unità appropriata al volo.
-
La temperatura memorizza solo un GUID. Qualsiasi richiesta get / set viene passata con il GUID a un servizio Web, che gestisce l'effettiva attività di conversione.
-
È impossibile distinguere dall'interfaccia definita, ma uno dei suddetti funzionerebbe (eccezioni di rete modulo).
-
Qualche altra risposta di cui non sono a conoscenza
Le risposte che selezionerei sono 1 e 4. Cioè, le proprietà definivano qualche interfaccia pubblica per la classe, ma nascondevano come la classe fosse effettivamente implementata. Le proprietà soddisfano "limitare l'accesso ad alcuni dei componenti dell'oggetto" nascondendo ciò che sono anche quei componenti. Insieme alla classe stessa, aiutano anche a "facilitare il raggruppamento dei dati con i metodi (o altre funzioni) che operano su quei dati", potendo condividere le informazioni tra loro.
TL; DR: le proprietà possono (e comunemente sono) utilizzate per supportare l'incapsulamento.