Domanda

Esiste una differenza tra avere una variabile const privata o una variabile di lettura statica privata in C # (oltre a dover assegnare la const un'espressione in fase di compilazione)?

Poiché sono entrambi privati, non esiste alcun collegamento con altre librerie. Quindi farebbe qualche differenza? Ad esempio, può fare la differenza? Stringhe internate? Qualcosa di simile?

È stato utile?

Soluzione

Bene, puoi usare i cons negli attributi, poiché esistono come tempo di compilazione. Non è possibile prevedere il valore di una variabile di sola lettura statica, poiché .cctor potrebbe inizializzarlo dalla configurazione ecc.

In termini di utilizzo, le costanti vengono inserite nel codice chiamante. Ciò significa che se si ricompila una libreria dll per cambiare una costante pubblica , ma non si cambiano i consumatori, questi utilizzerà comunque il valore originale. Con una variabile di sola lettura questo non accadrà. Il rovescio della medaglia è che le costanti sono (molto, molto leggermente) più veloci, poiché carica semplicemente il valore (piuttosto che doverlo de-referenziare).

Re interning; sebbene sia possibile farlo manualmente, questa è più comunemente una funzione di compilazione / runtime dei valori letterali; se si avvia un campo di sola lettura tramite un valore letterale:

someField = "abc";

quindi il " abc " verrà internato. Se lo leggi da Config, non lo sarà. Poiché una stringa costante deve essere letterale, verrà anche internata, ma vi si accede in modo diverso: di nuovo, la lettura dal campo è un de-riferimento, piuttosto che un ldstr .

Altri suggerimenti

In effetti, i due tipi non possono essere cambiati dopo essere stati inizializzati, ma ci sono alcune differenze tra loro:

  • 'const' deve essere inizializzato dove sono dichiarati (al momento della compilazione), mentre 'readonly' può essere inizializzato dove è dichiarato o all'interno del costruttore (runtime).

Ad esempio const potrebbe essere usato in questa situazione:

public class MathValues
{
  public const double PI = 3.14159;
}

E di sola lettura sarebbe meglio per questo caso:

public class Person
{
    public readonly DateTime birthDate;

    public Person(DateTime birthDate)
    {
        this.birthDate = birthDate;
    }
}

o

public class Person
{
    public readonly DateTime birthDate = new DateTime(1986, 1, 24);
}
  • 'const' è statico, quindi è condiviso tra tutte le istanze di quella classe e vi si può accedere direttamente (come MathValues.PI), mentre 'sola lettura' non è statico. Di conseguenza una dichiarazione come "const statica" è illegale perché const è statica, ma "staticamente di sola lettura" è legale

  • 'const' può contenere solo tipi integrali (sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, decimal, bool o string), un'enumerazione o un riferimento a null (non classi o strutture perché sono inizializzate in fase di esecuzione, con la parola chiave "new"), mentre "sola lettura" può contenere tipi, strutture o classi complesse (utilizzando la nuova parola chiave durante l'inizializzazione) ma non può contenere enumerazioni

Qualcosa da notare sulle costanti è che sono effettivamente archiviate nel tuo eseguibile, quindi dichiarandone molte aumenterà le dimensioni del tuo file eseguibile.

Normalmente, questo non è un grosso problema, ma un mio amico ha lavorato in un'azienda che ha imposto un "tutto deve essere const" regola e riesce ad aumentare significativamente la dimensione eseguibile compilata.

Ecco le differenze tra i campi const , di sola lettura e di sola lettura statici di C #. NET (da questo articolo ).

Costanti :

  • Statico per impostazione predefinita
  • Deve avere un valore di tempo di compilazione (ovvero: puoi avere " A " + " B " ma non puoi avere chiamate di metodo)
  • Può essere utilizzato negli attributi
  • Vengono copiati in ogni assembly che li utilizza (ogni assembly ottiene una copia locale dei valori)
  • Potrebbe essere dichiarato all'interno delle funzioni

Campi di istanza di sola lettura :

  • Vengono valutati quando viene creata l'istanza
  • Deve aver impostato il valore dal momento in cui il costruttore esce

Campi di sola lettura statici :

  • Vengono valutati quando l'esecuzione del codice raggiunge il riferimento di classe (ovvero: viene creata una nuova istanza o viene eseguito un metodo statico)
  • Deve aver valutato il valore entro il termine del costruttore statico
  • Non vuoi davvero mettere ThreadStaticAttribute su questi (poiché il costruttore statico verrà eseguito in un solo thread e imposterà il valore per il suo thread; tutti gli altri thread avranno questo valore non inizializzato)

Esiste una notevole differenza tra i campi const e di sola lettura in C # .Net

const è di default statico e deve essere inizializzato con un valore costante, che non può essere modificato in seguito. La modifica del valore non è consentita anche nei costruttori. Non può essere utilizzato con tutti i tipi di dati. Per ex DateTime. Non può essere utilizzato con il tipo di dati DateTime.

public const DateTime dt = DateTime.Today;  //throws compilation error
public const string Name = string.Empty;    //throws compilation error
public readonly string Name = string.Empty; //No error, legal

di sola lettura può essere dichiarato statico, ma non necessario. Non è necessario inizializzare al momento della dichiarazione. Il suo valore può essere assegnato o modificato tramite il costruttore. Pertanto, offre un vantaggio se utilizzato come membro della classe di istanza. Due diverse istanze possono avere un valore diverso del campo di sola lettura. Ad esempio -

class A
{
    public readonly int Id;

    public A(int i)
    {
        Id = i;
    }
}

Quindi il campo di sola lettura può essere inizializzato con valori specifici istantanei, come segue:

A objOne = new A(5);
A objTwo = new A(10);

Qui, l'istanza di objOne avrà il valore del campo di sola lettura come 5 e objTwo ha 10. Che non è possibile usando const.

In uso? Non proprio. I costi vengono valutati in fase di compilazione, mentre in sola lettura vengono valutati in fase di esecuzione. Puoi anche assegnare a una variabile di sola lettura un valore nel costruttore.

Un'altra cosa. Non ho visto questo nei commenti sopra, anche se potrei averlo perso. Non è possibile creare un array costante.

private const int[] values = new int[] { 1, 2, 3 };

Ma puoi crearlo usando un campo di sola lettura statico.

private static readonly int[] values = new int[] { 1, 2, 3 };

Quindi, se hai bisogno di una costante di array, come un elenco di valori consentiti, e un'enumerazione non sarebbe appropriata, la sola lettura statica è l'unica strada da percorrere. Ad esempio, se l'array avesse numeri interi nullable, in questo modo:

private static readonly int?[] values = new int?[] { null, 1, 2, 3 };

Non puoi fare quello con una costante, vero?

La differenza è che il valore di un campo statico di sola lettura è impostato in fase di esecuzione e può quindi essere modificato dalla classe contenente, mentre il valore di un campo const è impostato su una costante di tempo di compilazione.

Nel caso di sola lettura statica, la classe contenitore può modificarla solo

nella dichiarazione delle variabili (tramite un inizializzatore variabile) nel costruttore statico (costruttori di istanza, se non è statico) staticamente di sola lettura viene generalmente utilizzato se il tipo di campo non è consentito in una dichiarazione const o quando il valore non è noto al momento della compilazione.

Sono consentiti anche campi di sola lettura dell'istanza.

Ricorda che per i tipi di riferimento, in entrambi i casi (statico e di istanza) il modificatore di sola lettura impedisce solo di assegnare un nuovo riferimento al campo. In particolare, non rende immutabile l'oggetto indicato dal riferimento.

class Program

{

  public static readonly Test test = new Test();

  static void Main(string[] args)

  {

     test.Name = "Program";

     test = new Test(); // Error: A static readonly field cannot be assigned to (except in a static constructor or a variable initializer)

  }

}

class Test

{

   public string Name;

}

La differenza è che la sola lettura statica può essere modificata dalla classe contenente, ma const non può mai essere modificato e deve essere inizializzato su una costante di tempo di compilazione. Per espandere un po 'il caso statico di sola lettura, la classe contenente può solo modificarlo:

- nella dichiarazione della variabile (tramite un inizializzatore variabile).

- nel costruttore statico (costruttori di istanza se non è statico).


Parola chiave Const in C # .NET

Esempio: public const string abc = & # 8220; xyz & # 8221 ;; Inizializzato solo alla dichiarazione. Il valore viene valutato in fase di compilazione e non può essere modificato in fase di esecuzione. Un tentativo di cambiarlo provocherà un errore di compilazione. Const è già abbastanza statico. Poiché le classi e le strutture sono inizializzate in fase di esecuzione con una nuova parola chiave, non puoi impostare una costante su una classe o struttura. Ma deve essere uno dei tipi integrali. Parola chiave di sola lettura in C # .NET

Esempio: public readonly string abc; Può essere inizializzato nel codice di dichiarazione o nel codice del costruttore. Il valore viene valutato in fase di esecuzione. Può essere dichiarato come attributo a livello di istanza o statico. Un campo di sola lettura può contenere un oggetto complesso utilizzando la nuova parola chiave in fase di esecuzione.

I campi di sola lettura possono essere inizializzati nella dichiarazione o in un costruttore di una classe. Pertanto i campi di sola lettura possono avere valori diversi a seconda del costruttore utilizzato .

Un membro di sola lettura può anche essere utilizzato per le costanti di runtime come nell'esempio seguente:

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

I campi di sola lettura sono non implicitamente statici, e quindi la parola chiave statica può (deve) essere applicata esplicitamente a un campo di sola lettura se necessario. Ciò non è consentito per i campi const, che sono implicitamente statici.

I membri di sola lettura possono contenere oggetti complessi utilizzando la nuova parola chiave durante l'inizializzazione .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top