2014-09-27 13 views
28

C'è qualche differenza tra quanto segue?C# getter vs readonly

class C 
{ 
    // One: 
    public static readonly int ValueAsAMember = 42; 

    // Two: 
    public static int ValueAsAProperty { get { return 42; } } 
} 

io sono abituato a scrivere le costanti il ​​primo modo (a meno che siano private/interno, nel qual caso io uso la parola chiave const), ma di recente ho visto il secondo modulo.

C'è qualche vantaggio rispetto all'altro in termini di leggibilità, convenzione, prestazioni o altro?

+6

Questa probabilmente non è una buona domanda per SO. Ma darò comunque una risposta: usa 'const', che è più o meno equivalente alla tua prima riga. La seconda riga introduce una chiamata al metodo, che sarà probabilmente comunque in linea, ma qual è il punto? – siride

+3

Perché non usi "const"? – Crasher

+1

L'unico utilizzo che ho di 'readonly' è quando li ho impostati nei costruttori, tipicamente interfacce per TDD e designmode (WPF & SL). Usa 'const' in questo esempio e lo standard di denominazione C#, non c/C++ hehe;) –

risposta

11

Sì, c'è un vantaggio:

Se il valore diventa modificabile in qualsiasi punto nel futuro (per esempio, in una versione futura del codice), in un modo che è, per esempio, dipendente dal tempo , puoi supportarlo nella proprietà di sola lettura senza modificare l'interfaccia pubblica della tua classe.

Se è necessario sostituire un campo readonly con una proprietà, sarà necessario ricompilare eventuali altri assiemi che utilizzano la classe.

+3

ma ricorda che il campo 'readonly' può essere modificato solo in' costruttore' di 'classe' – harry180

+0

@ harry180: Certo, non chiederebbe altrimenti. Ecco perché ho detto che il campo 'readonly' dovrebbe essere sostituito con una proprietà nel caso descritto. –

+1

Ottimo punto; Non ci ho pensato. Apprezzo l'accuratezza della risposta di pescolino e la risposta di Daniel Mann agli altri riguardo la parola chiave const. Di proposito non ho chiesto di const per quella ragione esatta perché non faceva parte della discussione. Grazie a tutti per le loro risposte! – jia103

1

Il principale vantaggio per me è con readonly che è possibile dichiararlo in qualsiasi punto del codice. Ma avrai la possibilità di impostarlo solo una volta. Con il setter, si dichiara e si imposta in un colpo solo.

2

readonly è piacevole da utilizzare su cose che possono essere modificate solo nel costruttore. Esempi di questo sono servizi tipici come interfacce quando si segue il modello TDD.

Nel tuo esempio const è il migliore, dopo tutto è una costante.

readonly

const

Acclamazioni

3

Il mio modo di vedere, utilizzando il primo modo in cui descrive l'intenzione del valore migliore - che è che è immutabile. Quando una persona sta guardando l'interfaccia della classe, vedrà che il valore è di sola lettura e non dovrà chiedersi se può essere modificato in seguito (dal momento che nel secondo caso non può vedere l'implementazione della proprietà) .

Una cosa importante da notare circa const dichiarazioni (non credo che sia vero per readonly) è che cambiando il valore del campo costituisce un cambiamento API, anche se si sta solo cambiando il valore 42-41. Il motivo è che per consts, il valore è determinato durante la compilazione, il che significa che se compilo un modulo che usa la tua costante, e successivamente lo cambierai, userò ancora il vecchio valore finché non ricompilerò il mio modulo con il tuo nuovo versione.

1

Penso che la prima riga stia facendo qualcosa di costante o piuttosto di sola lettura usando una parola chiave readonly.

e la seconda riga utilizza una proprietà da implementare in sola lettura. Entrambi fanno lo stesso, ma se si confronta con l'IL, la proprietà aggiungerebbe alcune righe di codice aggiuntive alla DLL.

24

sono disponibili tre opzioni:

  • public static readonly int Value = 42;
  • public static Value { get { return 42; } }
  • public const Value = 42;

Scegli static readonly se il valore non cambierà in fase di esecuzione, ma potrebbe cambiare nelle future versioni di codice.

Scegliere una proprietà se il valore potrebbe cambiare in fase di esecuzione. Ovviamente non cambierà se si utilizza il codice indicato.

Scegliere const se il valore è in realtà una costante che non sarà nemmeno cambiare nelle future versioni (qualcosa come Math.PI o int.MinValue). E ovviamente l'uso di const è limitato dal tipo di valore.

La differenza tra const e static readonly è che il valore const verrà sostituito sul sito chiamata. Se si modifica il valore di uno const in una versione futura, tutti gli assembly che si basano sulla classe devono essere ricompilati utilizzando il nuovo valore.

La proprietà richiede una chiamata al metodo (chiamare un getter è una chiamata di metodo). Quindi se il valore è costante in fase di esecuzione non è necessario.

+1

"che significa: non selezionarlo per un valore costante" Er, perché no? –

+0

@BenAaronson: Fondamentalmente perché pensavo che ci sarebbe stato un po 'di overhead per la chiamata al metodo. Ma ripensandoci mi sono appena reso conto che la chiamata sarà in linea. Ho rimosso quel consiglio dubbioso. Grazie per la segnalazione. – pescolino

+0

+1 per la parte "non cambierà nemmeno nelle versioni future". Troppi programmatori dimenticano questa condizione. -1 per la parte "proprietà richiede un metodo call", poiché il compilatore può ottimizzarlo. – CodesInChaos

6

ci sono due grandi differenze:

La prima è che i campi non possono essere sulle interfacce, mentre le proprietà può. Quindi, se si desidera utilizzare questo in un'interfaccia, è necessario utilizzare la proprietà.

Il secondo, più interessante, è che i campi readonly POSSONO essere modificati, mentre l'oggetto è in costruzione. Prendere il seguente codice:

public class MyTestClass 
{ 
    public readonly int MyInt = 1; 

    public MyTestClass() 
    { 
     MyInt = 2; 
    } 
} 

Se un chiamante non

new MyTestClass().MyInt 

che riceveranno 2. Lo stesso vale per i costruttori statici per un readonly campo statico.

+0

+1 per menzionare le interfacce. Utile per disaccoppiare le implementazioni. – Alejandro