Was passiert genau während der String-Initialisierung?Was passiert während der String-Initialisierung?
string s = "Hello World!";
Wird es einen dieser Konstrukteure anrufen? Hier
public String(char* value);
public String(char[] value);
Was passiert genau während der String-Initialisierung?Was passiert während der String-Initialisierung?
string s = "Hello World!";
Wird es einen dieser Konstrukteure anrufen? Hier
public String(char* value);
public String(char[] value);
nahm ich einen Blick auf die CoreCLR-Repository, um zu sehen, was ldstr
tut unter der Haube (Filip Bulovic Antwort sehen) und fand den Weg, so etwas zu sein:
[vm/interpreter.cpp]
Die IL Dolmetscher Auswertungsschleife trifft case CEE_LDSTR
und ruft Interpreter::LdStr()
LdStr()
ConstructStringLiteral
Anrufe und leitet das Modul des aktuellen Verfahrens und der String-Zeiger (Strom IL Befehls Standort + 1)[vm/jithelpers.cpp]
ConstructStringLiteral
Anrufe Module::ResolveStringRef
[vm/ceeload.cpp]
ResolveStringRef
Anrufe InitializeStringData
, dann LoaderAllocator::GetStringObjRefPtrFromUnicodeString
[vm/loaderallocator.cpp]
GetStringObjRefPtrFromUnicodeString
rufen die LoaderAllocator spezifische Stringliteral Karte der GetStringLiteral
[vm/stringliteralmap.cpp]
GetStringLiteral
die String-Hashes und versuchen, das String-Objekt aus der lokalen String-Eintrag Hash-Tabelle zu erhalten . Falls gefunden, wird das String-Objekt aus der Hash-Tabelle zurückgegeben. Wenn nicht, wird ein Versuch unternommen, get the string object from the global string literal map. Wenn das Literal nicht von der globalen Karte gefunden wird, wird es mit GlobalStringLiteralMap::AddStringLiteral
zur globalen Karte hinzugefügt.AddStringLiteral
erstellt das COM + -Stringobjekt mit einem Aufruf an AllocateStringObject
, weist ein Objekthandle für es zu und fügt das Literal der Tabelle als den Schlüssel und das Objekt als den Wert hinzu.
AllocateStringObject
: die char Zählwert gezählt wird, ein call is made to the garbage collector eine Zeichenfolge dieser Größe zuzuweisen, konstant die Zeichenfolge an den COM + String-Objekt kopiert wird, wird der String-Objekt mit GetIsOnlyLowChars
getestet, wenn sie wahr ist, STRING_STATE_FAST_OPS
das Flag gesetzt ist im COM + -String-Objekt "...which indicates if the string can be sorted in a fast way. Das Flag wird in der Assembly gespeichert, die die String-Literale enthält. Wir stellen das Flag wieder her, wenn wir Strings aus der Assembly laden ... "
GetIsOnlyLowChars
hat eine bitweise UND mit ONLY_LOW_CHARS_MASK
und die Zeichen in der Zeichenfolge (die 0x80000000
ist) und gibt true zurück, wenn die Zeichenfolge nur Zeichen weniger enthält als 0x80 Die verwalteten (intern) Methoden String.IsFastSort()
ref |. src und String.IsAscii()
ref |. src nutzen dieseAbschließend Stringliterale nehmen einen ganz bestimmten Weg, der keine Anrufe an den verwalteten String(char *)
oder String(char[])
Konstruktor macht. Allerdings habe ich die Implementierung für diese Konstruktoren noch nicht gefunden, also kann ich nur annehmen, dass sie beide irgendwann an AllocateStringObject
anrufen.
Ich hoffe, diese Antwort passt zu Ihrer Vorstellung von "genau".
ist C#:
public static void Main (string[] args)
{
string hello = "Hello World!";
Console.WriteLine (hello);
}
und hier ist IL:
// method line 2
.method public static hidebysig
default void Main (string[] args) cil managed
{
// Method begins at RVA 0x20f4
.entrypoint
// Code size 13 (0xd)
.maxstack 2
.locals init (
string V_0)
IL_0000: ldstr "Hello World!"
IL_0005: stloc.0
IL_0006: ldloc.0
IL_0007: call void class [mscorlib]System.Console::WriteLine(string)
IL_000c: ret
} // end of method MainClass::Main
Die ldstr Anweisung drückt eine Objektreferenz (Typ O) zu einem neuen String-Objekt repräsentierte das spezifische String-Literal, das in den Metadaten gespeichert ist. Der Befehl ldstr weist die erforderliche Menge Speicher zu und führt jede Formatkonvertierung durch, die erforderlich ist, um das Zeichenfolgenliteral aus dem in der Datei verwendeten Formular in das zur Laufzeit erforderliche Zeichenfolgenformat zu konvertieren.
's' wird die Referenz des * interned * Strings' "Hello World!" 'Zugewiesen. Das String-Objekt wird von der Laufzeit erstellt, daher ist es eine gute Frage, nach den genauen Details zu fragen. Die definitive Antwort liegt irgendwo in [CoreCLR] (https://github.com/dotnet/coreclr). –