Frage Was ist der Unterschied zwischen const und readonly?


Was ist der Unterschied zwischen const und readonly und benutzt du eins über dem anderen?


989
2017-09-11 08:02


Ursprung


Antworten:


Abgesehen von dem scheinbaren Unterschied von

  • muss den Wert zum Zeitpunkt einer Definition für a angeben const VS readonly Werte können dynamisch berechnet werden, müssen aber zugewiesen werden, bevor der Konstruktor beendet wird. Danach wird er eingefroren.
  • Const's sind implizit static. Sie verwenden ein ClassName.ConstantName Notation, um auf sie zuzugreifen.

Es gibt einen feinen Unterschied. Betrachten Sie eine Klasse, die in definiert ist AssemblyA.

public class Const_V_Readonly
{
  public const int I_CONST_VALUE = 2;
  public readonly int I_RO_VALUE;
  public Const_V_Readonly()
  {
     I_RO_VALUE = 3;
  }
}

AssemblyB Verweise AssemblyA und verwendet diese Werte im Code. Wenn das kompiliert wird,

  • im Falle der const Wert, es ist wie ein Fund-ersetzen, der Wert 2 ist in die "gebacken" AssemblyBist IL. Das bedeutet, dass ich morgen aktualisieren werde I_CONST_VALUE bis 20 in der Zukunft. AssemblyB würde noch 2 haben, bis ich es neu kompiliere.
  • im Falle der readonly Wert, es ist wie ein ref zu einem Speicherort. Der Wert ist nicht eingebacken AssemblyBist IL. Dies bedeutet, dass wenn der Speicherort aktualisiert wird, AssemblyB erhält den neuen Wert ohne Neukompilierung. Also, wenn I_RO_VALUE ist auf 30 aktualisiert, Sie müssen nur erstellen AssemblyA. Alle Clients müssen nicht neu kompiliert werden.

Wenn Sie also sicher sind, dass sich der Wert der Konstante nicht ändert, verwenden Sie a const.

public const int CM_IN_A_METER = 100;

Wenn Sie jedoch eine Konstante haben, die sich ändern kann (z. B. W.r.t. Präzision), oder wenn Sie Zweifel haben, verwenden Sie a readonly.

public readonly float PI = 3.14;

Update: Aku muss eine Erwähnung bekommen, weil er zuerst darauf hingewiesen hat. Auch ich muss stecken, wo ich das gelernt habe .. Effektive C # - Bill Wagner


979
2017-09-11 08:24



Es gibt ein Problem mit Störungen! Wenn Sie eine Konstante von einer anderen Assembly referenzieren, wird ihr Wert direkt in die aufrufende Assembly kompiliert. Auf diese Weise ändert sich die Konstante in der referenzierten Assembly nicht in der aufrufenden Assembly!


237
2017-09-11 08:15



Konstanten

  • Konstanten sind standardmäßig statisch
  • Sie müssen einen Wert zur Kompilierungszeit haben (Sie können beispielsweise 3,14 * 2 haben, aber Methoden nicht aufrufen)
  • Kann innerhalb von Funktionen deklariert werden
  • Werden in jede Assembly kopiert, die sie verwendet (jede Assembly erhält eine lokale Kopie der Werte)
  • Kann in Attributen verwendet werden

Nur-Instanz-Felder

  • Muss den gesetzten Wert haben, bis der Konstruktor beendet wird
  • Werden ausgewertet, wenn Instanz erstellt wird

Statische Nur-Lese-Felder

  • Werden ausgewertet, wenn die Codeausführung die Klassenreferenz trifft (wenn eine neue Instanz erstellt oder eine statische Methode ausgeführt wird)
  • Muss zu dem Zeitpunkt, zu dem der statische Konstruktor fertig ist, einen ausgewerteten Wert haben
  • Es wird nicht empfohlen, ThreadStaticAttribute auf diese zu setzen (statische Konstruktoren werden nur in einem Thread ausgeführt und stellen den Wert für ihren Thread ein; bei allen anderen Threads wird dieser Wert nicht initialisiert)

125
2017-12-02 11:50



Nur um ReadOnly für Referenztypen hinzuzufügen, macht die Referenz nur die Werte readonly. Beispielsweise:

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
  }
}

48
2017-09-11 10:37



Das erklärt es. Zusammenfassung: const muss zur Deklarationszeit initialisiert werden, readonly kann im Konstruktor initialisiert werden (und hat somit einen anderen Wert abhängig vom verwendeten Konstruktor).

EDIT: Siehe Gishu's oben für den feinen Unterschied


37
2017-09-11 08:04



const: Kann nirgendwo geändert werden.

readonly: Dieser Wert kann nur im Konstruktor geändert werden. Kann in normalen Funktionen nicht geändert werden.


25
2018-05-21 13:21



Es gibt ein kleines Gotcha mit readonly. Ein schreibgeschütztes Feld kann mehrmals innerhalb des Konstruktors (der Konstruktoren) gesetzt werden. Auch wenn der Wert in zwei verschiedenen verketteten Konstruktoren gesetzt ist, ist er immer noch erlaubt.


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
    }
}

20
2017-10-19 22:14



A const ist eine Kompilierzeitkonstante, während readonly die Berechnung eines Wertes zur Laufzeit erlaubt und im Konstruktor oder Feldinitialisierer festgelegt wird. Ein 'const' ist also immer konstant, aber 'readonly' ist nur lesbar, sobald es zugewiesen ist.

Eric Lippert des C # -Teams hat mehr Informationen über verschiedene Arten von Unveränderlichkeit


19
2017-09-11 08:07



Ein konstantes Member wird zur Kompilierzeit definiert und kann zur Laufzeit nicht geändert werden. Konstanten werden als ein Feld deklariert const Schlüsselwort und muss initialisiert werden, wie sie deklariert sind.

public class MyClass
{
    public const double PI1 = 3.14159;
}

EIN readonly Mitglied ist wie eine Konstante, da es einen unveränderlichen Wert darstellt. Der Unterschied ist, dass a readonly member kann zur Laufzeit in einem Konstruktor initialisiert und initialisiert werden, wenn sie deklariert sind.

public class MyClass1
{
     public readonly double PI2 = 3.14159;

     //or

     public readonly double PI3;

     public MyClass2()
     {
         PI3 = 3.14159;
     }
}

const

  • Sie können nicht als deklariert werden static (Sie sind implizit statisch)
  • Der Wert der Konstante wird zur Kompilierzeit ausgewertet
  • Konstanten werden nur bei der Deklaration initialisiert

schreibgeschützt

  • Sie können entweder auf Instanzebene oder statisch sein
  • Der Wert wird zur Laufzeit ausgewertet
  • readonly kann in der Deklaration oder im Konstruktor durch Code initialisiert werden

19
2017-09-17 11:48



Hier ist ein weiterer Link demonstrieren, wie const nicht versionssicher oder relevant für Referenztypen ist.

Zusammenfassung:

  • Der Wert Ihrer Eigenschaft const wird zur Kompilierzeit festgelegt und kann zur Laufzeit nicht geändert werden
  • Const kann nicht als statisch markiert werden - das Schlüsselwort zeigt an, dass sie statisch sind, im Gegensatz zu schreibgeschützten Feldern, die dies können.
  • Const kann nichts außer Wert (primitive) Typen sein
  • Das Schlüsselwort readonly markiert das Feld als unveränderbar. Die Eigenschaft kann jedoch innerhalb des Konstruktors der Klasse geändert werden
  • Das Schlüsselwort readonly only kann auch mit static kombiniert werden, damit es sich wie ein const (zumindest auf der Oberfläche) verhält. Es gibt einen deutlichen Unterschied, wenn Sie die IL zwischen den beiden betrachten
  • const-Felder werden in AWL als "literal" markiert, während readonly "initonly" ist

14
2018-01-31 11:42