2009-10-14 8 views
10

Perché il reSharper suggerisce un campo di sola lettura per le "impostazioni" nel mio esempio di seguito?Perché il programma di suggerimento suggerisce i campi di sola lettura

Se ho capito bene, dovresti usare il modificatore readonly se cambi questo campo solo in costruttore, ma nel mio esempio lo cambio anche in un altro metodo della stessa classe.

Cosa mi manca?

public partial class OptionsForm : Form 
{ 
    private Settings settings; 

    public OptionsForm(Settings s) 
    { 
     settings = s; 
    } 

    private void SaveData() 
    { 
     settings.ProjectName = TextBoxProject.Text; 
    } 
} 
+1

Ok, e come disabilitarlo? Non sono riuscito a trovare le opzioni ... – andrecarlucci

risposta

24

Quando un tipo di riferimento viene dichiarato come readonly, il puntatore è immutabile, ma non l'oggetto a cui punta. Questo significa che:

  • un membro dati tipo di riferimento può essere inizializzato in modo da puntare a un un'istanza di una classe, ma una volta fatto questo non è possibile farlo punto ad un altro esempio di un classe al di fuori dei costruttori
  • il modificatore di sola lettura non ha alcun effetto sull'oggetto a cui fa riferimento il membro di dati di sola lettura .

Leggi un articolo dettagliato su questo

Mark a C# class data member as readonly when it’s read only

+1

Come risponde la domanda: "Perché ReSharper suggerisce un campo di sola lettura per le" impostazioni "nel mio esempio qui sotto?" ? – zvolkov

+0

Il collegamento menzionato nella risposta sopra non funziona. Penso che sia stato spostato su http://www.developer-corner.com/2009/01/mark-c-class-data-member-as-readonly.html – Raghav

+0

Sono d'accordo con @zvolkov. È spiegato nel link? In tal caso, parafrasare il collegamento qui. – jcollum

0

Non si cambiano le impostazioni al di fuori del costruttore, l'oggetto è lo stesso in SaveData. Le proprietà dell'oggetto potrebbero cambiare ma non il riferimento all'oggetto, quindi sembra avere senso da una prospettiva di Resharper.

0

Il metodo SaveData() non modifica la variabile delle impostazioni, ne modifica le proprietà. Il contenuto delle impostazioni (a cosa si riferisce) è impostato solo nel costruttore.

4

Ricordate la ragione principale per la codifica standard e modelli di progettazione è quello di rendere al più facile per le persone a capire il codice.

Marcando un campo come “sola lettura” si sta dicendo il lettore della classe che non hanno bisogno di prendere in considerazione come il valore del campo viene modificato.

Tuttavia, poiché l'oggetto al quale il campo di sola lettura punta può avere il suo cambiamento di stato, contrassegnare un campo come readonly può essere fuorviante a volte. Quindi pensa al tempo aiuta il lettore (ad es. Una persona) del tuo codice a capire il tuo design o no.

Se i valori nell'oggetto in cui il campo punta a modifiche all'interno della durata dell'oggetto, non penso che un campo debba essere contrassegnato come di sola lettura. (Ad esempio, l'oggetto puntato dovrebbe comportarsi come se fosse immutabile dal momento in cui l'appaltatore della classe viene chiamato)

(Tuttavia ci sono alcune eccezioni, ad esempio, è OK usare un campo di sola lettura per puntare a un logger ha persino pensato che il logger cambi lo stato del file di registro.)

+0

Quindi stai suggerendo che nel mio caso il modificatore 'readonly' confonderebbe il lettore? – sventevit

+0

@simon, sì, dato che i valori delle impostazioni vengono modificati, non lo segnerei in sola lettura. –

+0

Non penso che sia una buona interpretazione. Il modificatore di sola lettura rende il riferimento immutabile, ha usi specifici; quello che dice il tuo blockquote non è affatto giusto. Inoltre, perché hai deciso che il logger è un caso speciale accettabile? – nicodemus13

0

In realtà, hai ragione e Resharper è sbagliato. Un campo dovrebbe essere contrassegnato in sola lettura se è immutabile nella sua interezza.Nel tuo esempio se lo fai in sola lettura e attivi l'Analisi del codice di Microsoft, ti avverte che le Impostazioni hanno proprietà mutabili.

+0

Non vero. Ti suggerisco di guardare http://msdn.microsoft.com/en-us/library/acdd6hb7%28VS.71%29.aspx – blowdart

+0

Blowdart, il tuo link MSDN definisce il comportamento della parola chiave/compilatore senza entrare in specifiche di valore tipi controtipi di riferimento, né considerando la SEMANTICA della parola chiave. Ora, la parola chiave funziona perfettamente per i tipi di valore (e tipi di riferimento immutabili) ma ha implicazioni interessanti per i tipi di riferimento mutabili. Diciamo che il campo è una tabella hash. Contrassegnare il campo come readonly rende l'hashtable immutabile? No! Non è possibile modificare il puntatore in modo che punti ad un'altra tabella hash ma si può ANCORA cambiare i dati. Ecco perché non dovresti usarlo su tipi di riferimento mutabili. – zvolkov

0

Questo sembra essere un po 'strano, non posso immaginare che Eric Lippert et al, non abbia considerato l'ovvio fatto che rendere un riferimento immutabile non rende l'esempio puntato dal riferimento immutabile, benché menzionato La regola di analisi del codice supporta la visualizzazione di quelli precedenti (http://msdn.microsoft.com/en-us/library/ms182302(v=VS.100).aspx).

Non ha ancora alcun senso. Se le istanze mutabili non dovrebbero essere di sola lettura, allora, a mio avviso, dovrebbe essere un errore in fase di compilazione, altrimenti sembra piuttosto inutile.

Riesco a vedere l'uso di rendere un riferimento immutabile, piuttosto che l'istanza a cui punta.

1

ReSharper suggerisce fare "Impostazioni" sola lettura:

readonly private Settings settings; 

public OptionsForm(Settings s) 
{ 
    settings = s; 
} 

perché, al momento la scansione del codice si conclude che il campo "Impostazioni" si verifica solo nel costruttore per questa stessa classe.

Se howerver dovessi fornire una classe parziale o qualche altro codice in questa classe che ha modificato "impostazioni", non suggerirebbe più che fosse di sola lettura.

Una volta contrassegnato in sola lettura il compilatore segnala come avvertimenti vari abusi del settore, come ad esempio:

The left-hand side of an assignment must be an l-value 

che è lo stesso errore che si ottiene quando si tenta di assegnare un valore a una costante.

anche l'uso di ref e fuori modificatori parametri sono limitati.

Seguendo il suggerimento di ReSharpers verrai avvisato dal compilatore se tenti di utilizzare in modo errato un campo che intendi davvero non modificare dopo l'inizializzazione.

Problemi correlati