2015-06-26 7 views
9

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); 
+2

'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). –

Antwort

4

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:

  1. [vm/interpreter.cpp] Die IL Dolmetscher Auswertungsschleife trifft case CEE_LDSTR und ruft Interpreter::LdStr()
  2. LdStr()ConstructStringLiteral Anrufe und leitet das Modul des aktuellen Verfahrens und der String-Zeiger (Strom IL Befehls Standort + 1)
  3. [vm/jithelpers.cpp]ConstructStringLiteral Anrufe Module::ResolveStringRef
  4. [vm/ceeload.cpp]ResolveStringRef Anrufe InitializeStringData, dann LoaderAllocator::GetStringObjRefPtrFromUnicodeString
  5. [vm/loaderallocator.cpp]GetStringObjRefPtrFromUnicodeString rufen die LoaderAllocator spezifische Stringliteral Karte der GetStringLiteral
  6. [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.
  7. 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 diese
  8. Der ganze Weg zurück in [vm/interpreter.cpp]: Der String-Objekt-Handle wird an den Stack übergeben.

Abschließ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".

2

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.

Verwandte Themen