'const string' vs. 'static readonly string' in C #


Antworten:


170

Wenn Sie eine constZeichenfolge verwenden, bettet der Compiler den Wert der Zeichenfolge zur Kompilierungszeit ein .
Wenn Sie einen constWert in einer anderen Assembly verwenden, dann die ursprüngliche Assembly aktualisieren und den Wert ändern, wird die Änderung der anderen Assembly erst angezeigt , wenn Sie sie neu kompilieren .

Ein static readonlyString ist ein normales Feld, das zur Laufzeit nachgeschlagen wird. Wenn daher der Wert des Felds in einer anderen Assembly geändert wird, werden die Änderungen angezeigt, sobald die Assembly geladen wird, ohne dass eine Neukompilierung erforderlich ist.

Dies bedeutet auch, dass eine static readonlyZeichenfolge nicht konstante Elemente wie Environment.UserNameoder verwenden kann DateTime.Now.ToString(). Eine constZeichenfolge kann nur mit anderen Konstanten oder Literalen initialisiert werden.
Außerdem kann eine static readonlyZeichenfolge in einem statischen Konstruktor festgelegt werden. Eine constZeichenfolge kann nur inline initialisiert werden.

Beachten Sie, dass a static stringgeändert werden kann; Sie sollten static readonlystattdessen verwenden.


25
1, und die offensichtliche Schlussfolgerung aus praktischem und semantischen Point-of-View: constnur für Konstanten verwendet werden soll - die Werte der Konstanten sind , die nie , nie , nie ändern.
LukeH

3
@LukeH ist niemals ein bisschen stark. Ich kann mir nichts Schlimmes vorstellen, das passieren würde, wenn man eine private Zeichenfolge als const deklarieren und zwischen zwei Neukompilierungsereignissen ändern würde.
Brenda Bell

5
@Brenda: Ich gebe zu, dass ich private constfür Werte verwende, die streng genommen keine Konstanten sind. Im Grunde ist es Missbrauch constfür Mikrooptimierungszwecke. Ich werde zu meiner Aussage "niemals, niemals, niemals" stehen , auch wenn sie mich zu einem Heuchler macht. ;)
LukeH

Was ist mit der Leistung insbesondere bei Saiten? Wird jede const-Verwendung eine neue Kopie einer Zeichenfolge im Speicher erzeugen?
Andrii

@Andrii nein, konstante Strings werden einmal erstellt. Jede Verwendung hat dieselbe Referenz im Speicher.
Migg

43

Hier ist eine gute Aufschlüsselung der Vor- und Nachteile :

Es scheint also, dass Konstanten verwendet werden sollten, wenn es sehr unwahrscheinlich ist, dass sich der Wert jemals ändert, oder wenn keine externen Apps / Bibliotheken die Konstante verwenden. Statische schreibgeschützte Felder sollten verwendet werden, wenn eine Laufzeitberechnung erforderlich ist oder wenn externe Verbraucher ein Faktor sind.


19
Sehr interessanter Punkt aus dem Artikel - "Auf hoher Ebene werden Konstanten offensichtlich zur Kompilierungszeit behandelt, während statische schreibgeschützte Felder zum Zeitpunkt ihrer Auswertung zur Laufzeit festgelegt werden. Die Tatsache, dass konstante Werte vom Compiler ersetzt werden bedeutet, dass jede Bibliothek / Assembly, die auf den konstanten Wert verweist, neu kompiliert werden muss, wenn sich der konstante Wert ändert. Bibliotheken, die auf ein statisches schreibgeschütztes Feld verweisen, verweisen auf das Feld und nicht auf den Wert, sodass sie Änderungen im Feld ohne Notwendigkeit erfassen zur Neukompilierung "
s_hewitt

1
Ja, das habe ich auch gelesen und hatte einen Moment Zeit. Das wusste ich definitiv nicht.
Spinon

Hier ist die zwischengespeicherte Version von Google: webcache.googleusercontent.com/…
Spinon

2
Der Referenzlink ist nicht mehr verfügbar.
Salomon Zhang

Dies ist eine hervorragende Ergänzung zu der als Lösung gekennzeichneten Antwort. Das Definieren der Verwendung ist sehr hilfreich. +1 von mir.
Bonez024

11

const

public const string MyStr;

ist eine Kompilierungszeitkonstante (Sie können sie beispielsweise als Standardparameter für einen Methodenparameter verwenden) und wird bei Verwendung einer solchen Technologie nicht verschleiert

static readonly

public static readonly string MyStr;

ist Laufzeitkonstante . Dies bedeutet, dass es beim Start der Anwendung und nicht vorher ausgewertet wird. Aus diesem Grund kann es beispielsweise nicht als Standardparameter für eine Methode (Kompilierungsfehler) verwendet werden. Der darin gespeicherte Wert kann verschleiert werden.


6

OQ fragte nach static stringvs.const . Beide haben unterschiedliche Anwendungsfälle (obwohl beide als statisch behandelt werden).

Verwenden Sie const nur für wirklich konstante Werte (z. B. Lichtgeschwindigkeit - aber auch diese variiert je nach Medium). Der Grund für diese strenge Richtlinie ist, dass der const-Wert durch die Verwendung der const in Assemblys ersetzt wird, die darauf verweisen. Dies bedeutet, dass Versionsprobleme auftreten können, wenn sich die const an ihrem Definitionsort ändert (dh es sollte keine Konstante gewesen sein) Nach alldem). Beachten Sie, dass dies sogar private constFelder betrifft , da Sie möglicherweise Basis- und Unterklassen in verschiedenen Assemblys haben und private Felder vererbt werden .

Statische Felder sind an den Typ gebunden, in dem sie deklariert sind. Sie werden zur Darstellung von Werten verwendet, die für alle Instanzen eines bestimmten Typs gleich sein müssen. Diese Felder können beliebig oft geschrieben werden (sofern nicht schreibgeschützt).

Wenn Sie static readonlyvs gemeint haben const, dann würde ich static readonlyfür fast alle Fälle empfehlen, weil es zukunftssicherer ist.


Von wem ist dieses "OQ", von dem Sie sprechen?
Peter Mortensen

"Ursprüngliche Frage"
Ben Aston

0

Sie können den Wert von a static readonly stringnur im staticKonstruktor der Klasse oder in einem Variableninitialisierer ändern, während Sie den Wert einer constZeichenfolge nirgendwo ändern können .


2
Ich sehe nicht, wie dies etwas hinzufügt, das über das hinausgeht, was die vorhandenen Antworten bereits sagen.
Fund Monica Klage
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.