[c#] Qual è la differenza tra const e readonly?


Answers

C'è un pasticcio con le Sense! Se si fa riferimento a una costante da un altro assieme, il suo valore verrà compilato direttamente nell'assieme di chiamata. In questo modo quando aggiorni la costante nell'assieme di riferimento non cambierà nell'assieme di chiamata!

Question

Qual è la differenza tra const e readonly e usi l'una rispetto all'altra?




La parola chiave readonly è diversa dalla parola chiave const . Un campo const può essere inizializzato solo alla dichiarazione del campo. Un campo di sola lettura può essere inizializzato o alla dichiarazione o in un costruttore . Pertanto, i campi di sola lettura possono avere valori diversi a seconda del costruttore utilizzato. Inoltre, mentre un campo const è una costante in fase di compilazione , il campo readonly può essere utilizzato per le costanti di runtime come nell'esempio seguente:

public static readonly uint timeStamp = (uint)DateTime.Now.Ticks;



Uno dei membri del team nel nostro ufficio ha fornito le seguenti indicazioni su quando utilizzare const, static e readonly:

  • Usa const quando hai una variabile di un tipo che puoi conoscere al runtime (string letteral, int, double, enum, ...) che vuoi che tutte le istanze o i consumatori di una classe abbiano accesso a dove il valore non dovrebbe cambiare.
  • Usa statico quando hai dati che vuoi che tutte le istanze o i consumatori di una classe abbiano accesso a dove il valore può cambiare.
  • Usa statico readonly quando hai una variabile di un tipo che non puoi sapere in runtime (oggetti) a cui vuoi che tutte le istanze o i consumatori di una classe abbiano accesso dove il valore non dovrebbe cambiare.
  • Usa readonly quando hai una variabile a livello di istanza che saprai al momento della creazione dell'oggetto che non dovrebbe cambiare.

Un'ultima nota: un campo const è statico, ma l'inverso non è vero.




La parola chiave readonly è diversa dalla parola chiave const. Un campo const può essere inizializzato solo alla dichiarazione del campo. Un campo di sola lettura può essere inizializzato o alla dichiarazione o in un costruttore. Pertanto, i campi di sola lettura possono avere valori diversi a seconda del costruttore utilizzato. Inoltre, mentre un campo const è una costante in fase di compilazione, il campo readonly può essere utilizzato per le costanti di runtime come nell'esempio seguente:

public static readonly uint l1 = (uint) DateTime.Now.Ticks;



Ecco un altro link che dimostra come const non è sicuro per la versione, o rilevante per i tipi di riferimento.

Riepilogo :

  • Il valore della proprietà const è impostato al momento della compilazione e non può essere modificato in fase di runtime
  • Const non può essere contrassegnato come statico: la parola chiave indica che sono statici, a differenza dei campi readonly che possono.
  • Const non può essere nient'altro che tipi di valore (primitivi)
  • La parola chiave readonly contrassegna il campo come non modificabile. Tuttavia la proprietà può essere modificata all'interno del costruttore della classe
  • La parola chiave only onlyly può anche essere combinata con static per farlo agire allo stesso modo di un const (atleast sulla superficie). C'è una differenza marcata quando si guarda l'IL tra i due
  • i campi const sono contrassegnati come "letterali" in IL mentre readonly è "initonly"



Credo che un valore const sia lo stesso per tutti gli oggetti (e debba essere inizializzato con un'espressione letterale), mentre readonly può essere diverso per ogni istanza ...




Giusto per aggiungere, ReadOnly per i tipi di riferimento rende solo il riferimento in sola lettura non i valori. Per esempio:

public class Const_V_Readonly
{
  public const int I_CONST_VALUE = 2;
  public readonly char[] I_RO_VALUE = new Char[]{'a', 'b', 'c'};

  public UpdateReadonly()
  {
     I_RO_VALUE[0] = 'V'; //perfectly legal and will update the value
     I_RO_VALUE = new char[]{'V'}; //will cause compiler error
  }
}



Costante

Dobbiamo fornire il valore al campo const quando viene definito. Il compilatore salva quindi il valore della costante nei metadati dell'assembly. Ciò significa che una costante può essere definita solo per il tipo primitivo come booleano, char, byte e così via. Le costanti sono sempre considerate membri statici, non membri di istanze.

Sola lettura

I campi di sola lettura possono essere risolti solo in fase di runtime. Ciò significa che possiamo definire un valore per un valore utilizzando il costruttore per il tipo in cui è dichiarato il campo. La verifica viene eseguita dal compilatore in modo che i campi di sola lettura non vengano scritti da alcun metodo diverso dal costruttore.

Maggiori informazioni su entrambi spiegati qui in questo articolo




Le variabili costanti sono dichiarate e inizializzate in fase di compilazione. Il valore non può essere modificato dopo i reparti. Le variabili di sola lettura verranno inizializzate solo dal costruttore statico della classe. La sola lettura viene utilizzata solo quando si desidera assegnare il valore in fase di esecuzione.




C'è un piccolo trucco con readonly. Un campo di sola lettura può essere impostato più volte all'interno del / i costruttore / i. Anche se il valore è impostato su due diversi costruttori concatenati, è ancora consentito.


public class Sample {
    private readonly string ro;

    public Sample() {
        ro = "set";
    }

    public Sample(string value) : this() {
        ro = value; // this works even though it was set in the no-arg ctor
    }
}



const : non può essere modificato da nessuna parte.

readonly : questo valore può essere modificato solo nel costruttore. Non può essere cambiato in normali funzioni.




Una costante sarà compilata nel consumatore come valore letterale mentre la stringa statica servirà come riferimento al valore definito.

Come esercizio, prova a creare una libreria esterna e consumala in un'applicazione console, quindi modifica i valori nella libreria e ricompilala (senza ricompilare il programma consumer), rilascia la DLL nella directory ed esegui manualmente l'EXE, dovresti trovare che la stringa costante non cambia.




Una cosa da aggiungere a ciò che le persone hanno detto sopra. Se si dispone di un assembly che contiene un valore di sola lettura (ad esempio, MaxFooCount = 4;), è possibile modificare il valore che chiama gli assembly inviando una nuova versione di quell'assembly con un valore diverso (ad esempio, readFly MaxFooCount = 5;)

Ma con un const, sarebbe piegato nel codice del chiamante quando il chiamante è stato compilato.

Se hai raggiunto questo livello di competenza di C #, sei pronto per il libro di Bill Wagner, Effective C #: 50 modi specifici per migliorare il tuo C # che risponde a questa domanda in dettaglio, (e 49 altre cose).




ReadOnly: il valore verrà inizializzato solo una volta dal costruttore della classe.
const: può essere inizializzato in qualsiasi funzione ma solo una volta




Un const deve essere hard-coded , dove come readonly può essere impostato nel costruttore della classe.




Related