tl; dr für lokale Variablen mit Literalwerten const
macht überhaupt keinen Unterschied.
Ihre Unterscheidung von "Insider-Methoden" ist sehr wichtig. Schauen wir es uns an und vergleichen es dann mit const
Feldern.
Const lokale Variablen
Der einzige Vorteil einer const
lokalen Variablen besteht darin, dass der Wert nicht neu zugewiesen werden kann.
Allerdings const
beschränkt sich auf primitive Typen ( int
, double
, ...) und string
, die ihre Anwendbarkeit begrenzt.
Exkurs: Es gibt Vorschläge für den C # -Compiler, ein allgemeineres Konzept von "schreibgeschützten" Einheimischen ( hier ) zu ermöglichen, das diesen Vorteil auf andere Szenarien ausweiten würde. Sie werden wahrscheinlich nicht als gedacht werden const
aber, und wahrscheinlich ein anderes Schlüsselwort für solche Erklärungen (dh haben würden let
oder readonly var
oder so ähnlich).
Betrachten Sie diese beiden Methoden:
private static string LocalVarString()
{
var s = "hello";
return s;
}
private static string LocalConstString()
{
const string s = "hello";
return s;
}
Im eingebauten Release
Modus sehen wir die folgende (gekürzte) IL:
.method private hidebysig static string LocalVarString() cil managed
{
ldstr "hello"
ret
}
.method private hidebysig static string LocalConstString() cil managed
{
ldstr "hello"
ret
}
Wie Sie sehen können, produzieren beide genau die gleiche IL. Ob das Lokal s
ist const
oder nicht, hat keinen Einfluss.
Gleiches gilt für primitive Typen. Hier ist ein Beispiel mit int
:
private static int LocalVarInt()
{
var i = 1234;
return i;
}
private static int LocalConstInt()
{
const int i = 1234;
return i;
}
Und wieder die IL:
.method private hidebysig static int32 LocalVarInt() cil managed
{
ldc.i4 1234
ret
}
.method private hidebysig static int32 LocalConstInt() cil managed
{
ldc.i4 1234
ret
}
Wir sehen also wieder keinen Unterschied. Hier kann es keinen Leistungs- oder Speicherunterschied geben. Der einzige Unterschied besteht darin, dass der Entwickler das Symbol nicht neu zuweisen kann.
Const-Felder
Der Vergleich eines const
Feldes mit einem variablen Feld ist unterschiedlich. Ein nicht konstantes Feld muss zur Laufzeit gelesen werden. Am Ende haben Sie also IL wie folgt:
ldc.i4 1234
ldsfld int32 MyProject.MyClass::_myInt
Es ist klar zu sehen, wie dies zu einem Leistungsunterschied führen kann, vorausgesetzt, die JIT kann selbst keinen konstanten Wert inline setzen.
Ein weiterer wichtiger Unterschied besteht in öffentlichen Konstantenfeldern, die von Assemblys gemeinsam genutzt werden. Wenn eine Assembly ein const-Feld verfügbar macht und eine andere es verwendet, wird der tatsächliche Wert dieses Felds zur Kompilierungszeit kopiert . Dies bedeutet, dass der alte (und möglicherweise falsche) Wert verwendet wird, wenn die Assembly, die das const-Feld enthält, aktualisiert wird, die using-Assembly jedoch nicht neu kompiliert wird.
Const-Ausdrücke
Betrachten Sie diese beiden Erklärungen:
const int i = 1 + 2;
int i = 1 + 2;
Für das const
Formular muss die Addition zur Kompilierungszeit berechnet werden, dh die Nummer 3 wird in der IL gespeichert.
Für die Nichtform const
kann der Compiler die Additionsoperation in der IL ausgeben, obwohl die JIT mit ziemlicher Sicherheit eine grundlegende Optimierung der konstanten Faltung anwenden würde, so dass der generierte Maschinencode identisch wäre.
Der C # 7.3-Compiler gibt den ldc.i4.3
Opcode für beide oben genannten Ausdrücke aus.
const
. Es gibt dem Compiler keine zusätzlichen Informationen. Überprüfen Sie diese Antwort für weitere Details.