2009-04-21 11 views
17

C'è qualche differenza interna tra il C# modo zucchero sintattico di fare proprietà:È OK usare una variabile pubblica in C# se è in sola lettura?

public string FirstName { get; set; } 

e solo facendo le variabili pubbliche in questo modo:

public string LastName; 

Suppongo che il primo modo è preferito e il secondo a essere evitato. Tuttavia, vedo spesso questo tipo di proprietà di sola lettura in uso che è una forma del secondo tipo di cui sopra:

public readonly string InternalCode; 

È questo il modo in cui un best-practice per creare proprietà di sola lettura?

using System; 

namespace TestProps 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      Customer customer = new Customer(); 
      customer.FirstName = "Jim"; 
      customer.LastName = "Smith"; 
      customer.Show(); 
     } 
    } 

    class Customer 
    { 
     public string FirstName { get; set; } //prefered 
     public string LastName; //avoid 
     public readonly string InternalCode; //??? 

     public Customer() 
     { 
      InternalCode = "234729834723984"; 
     } 

     public void Show() 
     { 
      Console.WriteLine("{0}, {1} ({2})", LastName, FirstName, InternalCode); 
      Console.ReadLine(); 
     } 
    } 
} 

risposta

17

Dal momento che non ha risposto (ancora) e nessun altro ancora riferimento a questo: c'è un grande articolo su questo argomento da Jon Skeet, che modifica il suo libro C# in modo approfondito (dare crediti a Jon):

Why Properties Matter

+0

quell'articolo era un due pagine che rispondevano direttamente alla mia domanda, grazie! Capisco da ciò che Jon non approverebbe nemmeno "public publicallyly bool IsValid;" a meno che, come cita alla fine, sia in una classe nidificata –

+1

Per quelli di noi che cercano solo una risposta e non un lungo articolo, potresti aggiungere un avviso di spoiler qui e darci la risposta sì o no? – DOK

+0

L'articolo Skeet fa in realtà un paio di eccezioni, una delle quali potrebbe essere applicata a questa domanda. Secondo l'articolo, "farò una piccola eccezione per i campi statici di sola lettura come string.Empty". Questa domanda avrebbe potuto essere modificata e spostando l'assegnazione dal costruttore sulla stessa riga sarebbe statico public readonly stringa InternalCode = "234729834723984"; In quanto tale, sarebbe un "campo statico di sola lettura" proprio come descritto da Skeet. – John

1

Sì. è OK avere una variabile pubblica di sola lettura (è solo che possono essere inizializzate al momento della definizione o del costruttore).

ad es. Decimal.MaxValue

La proprietà pubblica di sola lettura è buona, se il valore di supporto cambia (diverso da quello con cui è stato inizializzato).

ad es. Environment.TickCount

Ho pensato che Environment.NewLine sarà una variabile pubblica di sola lettura. Bene, si tratta di una proprietà pubblica (ottenere solo) e il motivo potrebbe essere quello di mantenere la compatibilità su diverse piattaforme.

+0

Cosa c'è di sbagliato in questo? Si prega di inviare il motivo quando down-voting. Mi aiuterà a capire il mio errore. Grazie. – shahkalpesh

+0

Nessun voto da parte mia, ma in realtà Decimal.MaxValue è un const e non un campo di istanza (Leggi l'articolo di Jon Skeet collegato nella mia risposta per motivi di non esporre i campi) –

3

L'utilizzo di una proprietà fornisce un'interfaccia più resistente ai cambiamenti in futuro. Diciamo un po 'di tempo in futuro, viene presa la decisione di aggiungere un prefisso al codice interno.

L'utilizzo di una variabile pubblica in sola lettura espone la struttura interna e sarà difficile aggiungere il prefisso a ogni riga in cui è stata utilizzata la variabile interna della classe.

utilizzando una proprietà, si può semplicemente scrivere il seguente

public string InternalCode { 
    get { return _prefix + _internalCode; } 
} 

e il gioco è fatto!

+0

una volta risolti tutti gli errori del compilatore :-) –

+0

Cosa errori del compilatore? –

+0

Errore Il modificatore 'readonly' non è valido per questo articolo –

3

A mio parere, è ok per esporre i campi pubblici (soprattutto se sono readonly o const). Detto questo, direi che nell'esempio che stai presentando, probabilmente andrei con le proprietà dato che ti daranno 2 vantaggi (oltre i campi): 1) incapsulamento migliore e potresti permetterti di adattare il tuo codice nel futuro e 2) se stai facendo il binding dei dati, allora hai bisogno delle proprietà.

0

risposta breve: pubblico const è ok, in sola lettura pubblica non necessariamente, get pubblico senza impostare non neccessarily. Gli oggetti che non possono essere modificati senza essere assegnati possono essere ok. I tipi di riferimento sono pericolosi in quanto è ancora possibile modificare i loro valori, anche se non è possibile modificare il riferimento stesso.

Il problema con la parola chiave readonly è che non significa ciò che si intenderebbe logicamente in sola lettura/immutabile. Significa più come "può essere assegnato solo nel costruttore". I riferimenti non possono essere modificati, ma i suoi valori possono. Sfortunatamente non esiste una parola chiave "reale" di sola lettura fornita da C#. Vedere anche https://blogs.msdn.microsoft.com/ericlippert/2007/11/13/immutability-in-c-part-one-kinds-of-immutability/

Le proprietà non possono avere la parola chiave readonly (https://titombo.wordpress.com/2012/11/11/using-the-c-modifiers/). Come altri hanno notato, è possibile utilizzare una proprietà e definire solo get e nessun insieme, sebbene non sia possibile impostare tale proprietà nel costruttore. Utilizzando un set privato, è possibile impostare la proprietà da annywhere nella classe, non solo nel costruttore. Il campo di sola lettura sarebbe un po 'più restrittivo.

Problemi correlati