Freigeben über


System.String.Intern-Methode

Hinweis

Dieser Artikel enthält ergänzende Hinweise zur Referenzdokumentation für diese API.

Die Common Language Runtime verwaltet eine Tabelle, die als interner Pool bezeichnet wird und einen einzelnen Verweis für jeden eindeutigen Zeichenfolgenwert enthält. Die Intern Methode verwendet den intern-Pool, um nach einer Zeichenfolge zu suchen, die dem Wert von strentspricht. Wenn keine solche Zeichenfolge vorhanden ist, wird eine Referenz zu str dem Pool hinzugefügt, und diese Referenz wird zurückgegeben. (Im Gegensatz dazu gibt die IsInterned(String) Methode einen NULL-Verweis zurück, wenn die angeforderte Zeichenfolge nicht im internen Pool vorhanden ist.)

Der Internpool kann von der Laufzeit verwendet werden, um Zeichenfolgenspeicher zu sparen. Die automatische Internierung von Zeichenfolgenliteralen ist jedoch nicht garantiert – je nachdem, wie die Assembly kompiliert und ausgeführt wurde, werden einige Literale möglicherweise nicht zum Pool hinzugefügt.

Im folgenden Beispiel weist die Zeichenfolge s1 den Wert "MyTest" auf. Die System.Text.StringBuilder Klasse generiert ein neues Zeichenfolgenobjekt mit demselben Wert wie s1. Ein Verweis auf diese Zeichenfolge wird zugewiesen s2. Die Intern Methode sucht nach einer Zeichenfolge mit demselben Wert wie s2. Wenn s1 bereits intern ist (z. B. weil für die Assembly eine Zeichenfolgen-Literal-Internierung erforderlich ist), gibt die Methode denselben Verweis wie s1 zurück, der dann s3 zugewiesen wird, und s1 und s3 werden als gleich verglichen. Andernfalls wird ein neuer internierter Eintrag für s2 erstellt und s3 zugewiesen, und s1 und s3 werden ungleich verglichen. In beiden Fällen werden s1 und s2 als ungleich verglichen, da sie auf verschiedene Objekte verweisen.

string s1 = "MyTest"; 
string s2 = new StringBuilder().Append("My").Append("Test").ToString(); 
string s3 = String.Intern(s2); 
Console.WriteLine((Object)s2==(Object)s1); // Different references.
Console.WriteLine((Object)s3==(Object)s1); // The same reference.
let s1 = "MyTest"
let s2 = StringBuilder().Append("My").Append("Test").ToString()
let s3 = String.Intern s2
printfn $"{s2 :> obj = s1 :> obj}" // Different references.
printfn $"{s3 :> obj = s1 :> obj}" // The same reference.
Dim s1 As String = "MyTest" 
Dim s2 As String = New StringBuilder().Append("My").Append("Test").ToString() 
Dim s3 As String = String.Intern(s2) 
Console.WriteLine(CObj(s2) Is CObj(s1))      ' Different references.
Console.WriteLine(CObj(s3) Is CObj(s1))      ' The same reference.

Leistungsüberlegungen

Wenn Sie versuchen, die Gesamtmenge des Arbeitsspeichers zu reduzieren, den Ihre Anwendung zuweist, denken Sie daran, dass das Internieren einer Zeichenfolge zwei unerwünschte Nebenwirkungen hat. Zunächst wird der für interne Objekte zugewiesene String Speicher wahrscheinlich erst freigegeben, wenn die Common Language Runtime (CLR) beendet wird. Der Grund dafür ist, dass der CLR-Verweis auf das interne String Objekt beibehalten werden kann, nachdem Die Anwendung oder sogar Ihre Anwendungsdomäne beendet wurde. Zweitens müssen Sie zuerst die Zeichenfolge erstellen, um eine Zeichenfolge zu internieren. Der vom String-Objekt verwendete Speicher muss weiterhin zugewiesen werden, obwohl der Speicher schließlich garbage collection wird.

Das Enumerationsmitglied CompilationRelaxations.NoStringInterning kennzeichnet eine Assembly als nicht die Zeichenfolgenliteral-Internierung erforderlich. Standardmäßig erzeugt der C#-Compiler ein CompilationRelaxationsAttribute mit dem NoStringInterning-Flag in jeder Assembly, um die Leistung zu verbessern. Das bedeutet, dass es keine Garantie gibt, dass Zeichenfolgenliterale im Internspeicher hinzugefügt werden. Sie können NoStringInterning einer Assembly mithilfe des CompilationRelaxationsAttribute Attributs anpassen.

Wenn Sie eine App mit systemeigenem AOT veröffentlichen, wird das Deaktivieren NoStringInterning nicht unterstützt. Bei native AOT ist nicht garantiert, dass Zeichenfolgenliterale zum Intern-Pool hinzugefügt werden, daher wird möglicherweise keine Übereinstimmung für eine Zeichenfolge gefunden, die im Quellcode als Literal erscheint.