String.Intern(String) Methode

Definition

Ruft den Verweis des Systems auf den angegebenen Stringab.

public:
 static System::String ^ Intern(System::String ^ str);
public static string Intern(string str);
static member Intern : string -> string
Public Shared Function Intern (str As String) As String

Parameter

str
String

Eine Zeichenfolge, nach der im Internpool gesucht werden soll.

Gibt zurück

Der Verweis des Systems auf str, wenn es interniert ist; andernfalls ein neuer Verweis auf eine Zeichenfolge mit dem Wert von str.

Ausnahmen

str ist null.

Beispiele

Im folgenden Beispiel werden zwei Zeichenfolgen mit gleichen Werten erstellt und veranschaulicht, dass die Internierung denselben Verweis zurückgibt.

// Sample for String.Intern(String)
using System;
using System.Text;

class Sample
{
    public static void Main()
    {
        string s1 = new StringBuilder().Append("My").Append("Test").ToString();
        string s2 = new StringBuilder().Append("My").Append("Test").ToString();
        Console.WriteLine($"s1 == {s1}");
        Console.WriteLine($"s2 == {s2}");
        Console.WriteLine($"Are s1 and s2 equal in value? {s1 == s2}");
        Console.WriteLine($"Are s1 and s2 the same reference? {Object.ReferenceEquals(s1, s2)}");

        string i1 = String.Intern(s1);
        string i2 = String.Intern(s2);
        Console.WriteLine($"After interning:");
        Console.WriteLine($"  Are i1 and i2 equal in value? {i1 == i2}");
        Console.WriteLine($"  Are i1 and i2 the same reference? {Object.ReferenceEquals(i1, i2)}");
    }
}
/*
This example produces the following results:
s1 == MyTest
s2 == MyTest
Are s1 and s2 equal in value? True
Are s1 and s2 the same reference? False
After interning:
  Are i1 and i2 equal in value? True
  Are i1 and i2 the same reference? True
*/
// Sample for String.Intern(String)
open System
open System.Text

let s1 = StringBuilder().Append("My").Append("Test").ToString()
let s2 = StringBuilder().Append("My").Append("Test").ToString()
printfn $"s1 = {s1}"
printfn $"s2 = {s2}"
printfn $"Are s1 and s2 equal in value? {s1 = s2}"
printfn $"Are s1 and s2 the same reference? {Object.ReferenceEquals(s1, s2)}"

let i1 = String.Intern s1
let i2 = String.Intern s2
printfn "After interning:"
printfn $"  Are i1 and i2 equal in value? {i1 = i2}"
printfn $"  Are i1 and i2 the same reference? {Object.ReferenceEquals(i1, i2)}"
(*
This example produces the following results:
s1 = MyTest
s2 = MyTest
Are s1 and s2 equal in value? True
Are s1 and s2 the same reference? False
After interning:
  Are i1 and i2 equal in value? True
  Are i1 and i2 the same reference? True
*)
Imports System.Text

Class Sample

    Public Shared Sub Run()
        Dim s1 As String = New StringBuilder().Append("My").Append("Test").ToString()
        Dim s2 As String = New StringBuilder().Append("My").Append("Test").ToString()
        Console.WriteLine($"s1 = {s1}")
        Console.WriteLine($"s2 = {s2}")
        Console.WriteLine($"Are s1 and s2 equal in value? {s1 = s2}")
        Console.WriteLine($"Are s1 and s2 the same reference? {s1 Is s2}")

        Dim i1 As String = String.Intern(s1)
        Dim i2 As String = String.Intern(s2)
        Console.WriteLine("After interning:")
        Console.WriteLine($"  Are i1 and i2 equal in value? {i1 = i2}")
        Console.WriteLine($"  Are i1 and i2 the same reference? {i1 Is i2}")
    End Sub
End Class
'
's1 = MyTest
's2 = MyTest
'Are s1 and s2 equal in value? True
'Are s1 and s2 the same reference? False
'After interning:
'  Are i1 and i2 equal in value? True
'  Are i1 and i2 the same reference? True
'

Hinweise

! [HINWEIS] > Während String.Intern garantiert wird, dass zwei Zeichenfolgen mit gleichen Werten denselben internen Verweis zurückgeben, garantiert sie nicht, dass der zurückgegebene Verweis mit einem Zeichenfolgenliteral identisch ist.

        The common language runtime maintains a table, called the *intern pool*, that holds a single reference for each unique string value. The <xref:System.String.Intern*> method uses the intern pool to search for a string equal to the value of `str`. If no such string exists, a reference to `str` is added to the pool, and that reference is returned. (In contrast, the <xref:System.String.IsInterned(System.String)> method returns a null reference if the requested string doesn't exist in the intern pool.)

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.

Gilt für:

Weitere Informationen