1716 Stimmen

Was ist der Unterschied zwischen const und readonly in C#?

Was ist der Unterschied zwischen const y readonly in C#?

Wann würden Sie das eine dem anderen vorziehen?

2voto

Ramesh Rajendran Punkte 34781

Const und readonly sind ähnlich, aber nicht genau dasselbe. Ein const-Feld ist eine Kompilierzeitkonstante, was bedeutet, dass der Wert zur Kompilierzeit berechnet werden kann. Ein readonly-Feld ermöglicht zusätzliche Szenarien, in denen ein gewisser Code während der Konstruktion des Typs ausgeführt werden muss. Nach der Konstruktion kann ein readonly-Feld nicht mehr geändert werden.

Zum Beispiel können const-Mitglieder verwendet werden, um Mitglieder wie zu definieren:

struct Test
{
    public const double Pi = 3.14;
    public const int Zero = 0;
}

da Werte wie 3,14 und 0 Kompilierzeitkonstanten sind. Betrachten Sie jedoch den Fall, dass Sie einen Typ definieren und einige vorgefertigte Instanzen davon bereitstellen wollen. Sie könnten z.B. eine Klasse Color definieren und "Konstanten" für gängige Farben wie Black, White, etc. bereitstellen. Es ist nicht möglich, dies mit const-Mitgliedern zu tun, da die rechten Seiten keine Kompilierzeitkonstanten sind. Man könnte dies mit regulären statischen Mitgliedern tun:

public class Color
{
    public static Color Black = new Color(0, 0, 0);
    public static Color White = new Color(255, 255, 255);
    public static Color Red = new Color(255, 0, 0);
    public static Color Green = new Color(0, 255, 0);
    public static Color Blue = new Color(0, 0, 255);
    private byte red, green, blue;

    public Color(byte r, byte g, byte b) {
        red = r;
        green = g;
        blue = b;
    }
}

aber es gibt nichts, was einen Kunden von Color davon abhalten könnte, daran herumzupfuschen, indem er vielleicht die Schwarz- und Weißwerte vertauscht. Dies würde natürlich bei anderen Clients der Klasse Color für Verwirrung sorgen. Die "readonly"-Funktion löst dieses Szenario. Durch die einfache Einführung des readonly-Schlüsselworts in die Deklarationen wird die flexible Initialisierung beibehalten und gleichzeitig verhindert, dass der Client-Code die Werte vertauscht.

public class Color
{
    public static readonly Color Black = new Color(0, 0, 0);
    public static readonly Color White = new Color(255, 255, 255);
    public static readonly Color Red = new Color(255, 0, 0);
    public static readonly Color Green = new Color(0, 255, 0);
    public static readonly Color Blue = new Color(0, 0, 255);
    private byte red, green, blue;

    public Color(byte r, byte g, byte b) {
        red = r;
        green = g;
        blue = b;
    }
}

Interessant ist, dass const-Mitglieder immer statisch sind, während ein readonly-Mitglied entweder statisch oder nicht statisch sein kann, genau wie ein normales Feld.

Es ist möglich, ein einziges Schlüsselwort für diese beiden Zwecke zu verwenden, aber das führt entweder zu Versions- oder Leistungsproblemen. Nehmen wir für einen Moment an, wir würden ein einziges Schlüsselwort (const) verwenden und ein Entwickler würde schreiben:

public class A
{
    public static const C = 0;
}

und ein anderer Entwickler schrieb Code, der sich auf A stützte:

public class B
{
    static void Main() {
        Console.WriteLine(A.C);
    }
}

Kann sich der generierte Code nun auf die Tatsache verlassen, dass A.C eine Kompilierzeitkonstante ist? D.h., kann die Verwendung von A.C einfach durch den Wert 0 ersetzt werden? Wenn Sie dies mit "Ja" beantworten, bedeutet dies, dass der Entwickler von A die Art und Weise, wie A.C initialisiert wird, nicht ändern kann - dies bindet dem Entwickler von A unerlaubt die Hände. Wenn Sie diese Frage mit "Nein" beantworten, wird eine wichtige Optimierung verpasst. Vielleicht ist sich der Autor von A sicher, dass A.C immer Null sein wird. Die Verwendung von const und readonly erlaubt es dem Entwickler von A, die Absicht zu spezifizieren. Dies führt zu einem besseren Versionierungsverhalten und auch zu einer besseren Leistung.

1voto

ljs Punkte 35909

Im Prinzip können Sie einem statischen schreibgeschützten Feld zur Laufzeit einen nicht konstanten Wert zuweisen, während einem const-Feld ein konstanter Wert zugewiesen werden muss.

0voto

AlanR Punkte 1152

Der Hauptunterschied ist, dass Const das C-Äquivalent von #DEFINE ist. Die Zahl wird buchstäblich a-la precompiler ersetzt. Readonly wird tatsächlich wie eine Variable behandelt.

Diese Unterscheidung ist besonders wichtig, wenn Projekt A von einer öffentlichen Konstante aus Projekt B abhängig ist. Ihre Wahl von const/readonly wirkt sich nun auf das Verhalten von Projekt A aus:

Const: Projekt A fängt den neuen Wert nicht auf (es sei denn, es wird mit der neuen Konstante neu kompiliert), da es mit den eingefügten Konstanten kompiliert wurde.

Schreibgeschützt: Projekt A wird Projekt B immer nach dem Wert seiner Variablen fragen, so dass es den neuen Wert der öffentlichen Konstante in B übernimmt.

Ehrlich gesagt, würde ich empfehlen, Sie verwenden readonly für fast alles außer wirklich universelle Konstanten (z. B. Pi, Inches_To_Centimeters). Für alles, was sich möglicherweise ändern könnte, sage ich readonly verwenden.

Ich hoffe, das hilft, Alan.

0voto

Bigeyes Punkte 1324

Konst : Absolut konstanter Wert während der Lebensdauer der Anwendung.

Schreibgeschützt : Sie kann während der Laufzeit geändert werden.

0voto

Anthony Punkte 5038

Eines möchte ich den obigen Ausführungen noch hinzufügen. Wenn Sie eine Assembly haben, die einen Readonly-Wert enthält (z. B. readonly MaxFooCount = 4; ), können Sie den Wert, den aufrufende Assemblies sehen, ändern, indem Sie eine neue Version dieser Assembly mit einem anderen Wert versenden (z. B. readonly MaxFooCount = 5;)

Aber mit einer const, würde es in den Code des Aufrufers gefaltet werden, wenn der Aufrufer kompiliert wurde.

Wenn Sie diese Stufe der C#-Kenntnisse erreicht haben, sind Sie bereit für Bill Wagners Buch "Effective C#": 50 Specific Ways to Improve Your C# das diese Frage im Detail beantwortet (und 49 andere Dinge).

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X