System.String.Intern, metoda

Ten artykuł zawiera dodatkowe uwagi dotyczące dokumentacji referencyjnej dla tego interfejsu API.

Środowisko uruchomieniowe języka wspólnego oszczędza magazyn ciągów, utrzymując tabelę nazywaną pulą stażystyczną zawierającą pojedyncze odwołanie do każdego unikatowego ciągu literału zadeklarowanego lub utworzonego programowo w programie. W związku z tym wystąpienie ciągu literału o określonej wartości istnieje tylko raz w systemie.

Jeśli na przykład przypiszesz ten sam ciąg literału do kilku zmiennych, środowisko uruchomieniowe pobiera to samo odwołanie do ciągu literału z puli stażystów i przypisuje je do każdej zmiennej.

Metoda Intern używa puli intern do wyszukiwania ciągu równego strwartości . Jeśli taki ciąg istnieje, zwracane jest odwołanie do puli intern. Jeśli ciąg nie istnieje, zostanie dodane odwołanie str do puli intern, a następnie zostanie zwrócone odwołanie.

W poniższym przykładzie ciąg s1, który ma wartość "MyTest", jest już internowany, ponieważ jest to literał w programie. Klasa System.Text.StringBuilder generuje nowy obiekt ciągu, który ma taką samą wartość jak s1. Odwołanie do tego ciągu jest przypisane do s2. Metoda Intern wyszukuje ciąg, który ma taką samą wartość jak s2. Ponieważ taki ciąg istnieje, metoda zwraca to samo odwołanie przypisane do s1. To odwołanie jest następnie przypisywane do s3. Odwołania s1 i s2 porównują nierówne, ponieważ odwołują się do różnych obiektów; odwołania s1 i s3 są równe, ponieważ odwołują się do tego samego ciągu.

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.

Porównaj tę metodę z IsInterned metodą .

W poniższym przykładzie zmienna str1 ma przypisane odwołanie do String.Emptyelementu , a zmienna str2 jest przypisywana do String.Empty niej przez wywołanie Intern metody po przekonwertowaniu StringBuilder obiektu, którego wartość jest String.Empty ciągiem. Następnie odwołania zawarte w str1 elementach i str2 są porównywane pod kątem równości. str1 i str2 są równe.

string str1 = String.Empty;
string str2 = String.Empty;

StringBuilder sb = new StringBuilder().Append(String.Empty);
str2 = String.Intern(sb.ToString());

if ((object)str1 == (object)str2)
    Console.WriteLine("The strings are equal.");
else
    Console.WriteLine("The strings are not equal.");
let str1 = String.Empty
let str2 = String.Empty

let sb = StringBuilder().Append String.Empty
let str3 = String.Intern(string sb)

if (str1 :> obj) = (str3 :> obj) then
    printfn "The strings are equal."
else
    printfn "The strings are not equal."
Dim str1 As String = String.Empty
Dim str2 As String = String.Empty

Dim sb As StringBuilder = New StringBuilder().Append(String.Empty)
str2 = String.Intern(sb.ToString())

If CObj(str1) Is CObj(str2) Then
    Console.WriteLine("The strings are equal.")
Else
    Console.WriteLine("The strings are not equal.")
End If

Zagadnienia dotyczące wydajności

Jeśli próbujesz zmniejszyć łączną ilość pamięci przydzielanej przez aplikację, pamiętaj, że interning ciągu ma dwa niepożądane skutki uboczne. Po pierwsze, pamięć przydzielona dla obiektów internowanych String prawdopodobnie nie zostanie wydana, dopóki środowisko uruchomieniowe języka wspólnego (CLR) nie zakończy działania. Przyczyną jest to, że odwołanie CLR do internowanego obiektu może być utrwalane String po zakończeniu działania aplikacji, a nawet domeny aplikacji. Po drugie, aby internować ciąg, musisz najpierw utworzyć ciąg. Pamięć używana przez String obiekt musi być nadal przydzielana, mimo że pamięć zostanie ostatecznie odebrana.

Element CompilationRelaxations.NoStringInterning członkowski wyliczenia oznacza zestaw jako niewymagający interningu literału ciągu. Zestaw można zastosować NoStringInterning przy użyciu atrybutu CompilationRelaxationsAttribute . Ponadto w przypadku używania Ngen.exe (generatora obrazów natywnych) do skompilowania zestawu z wyprzedzeniem czasu wykonywania ciągi nie są internowane między modułami.