String.Intern(String) Metoda
Definicja
Ważne
Niektóre informacje odnoszą się do produktu w wersji wstępnej, który może zostać znacząco zmodyfikowany przed wydaniem. Firma Microsoft nie udziela żadnych gwarancji, jawnych lub domniemanych, w odniesieniu do informacji podanych w tym miejscu.
Pobiera odwołanie systemu do określonego Stringelementu .
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
Parametry
- str
- String
Ciąg do wyszukania w puli internowej.
Zwraca
Odwołanie systemu do strmetody , jeśli jest internowane; w przeciwnym razie nowe odwołanie do ciągu o wartości str.
Wyjątki
Parametr str ma wartość null.
Przykłady
Poniższy przykład tworzy dwa ciągi o równych wartościach i pokazuje, że ich przeplatanie daje to samo odwołanie.
// 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
'
Uwagi
! [UWAGA] > Chociaż
String.Interngwarantuje, że dwa ciągi o równych wartościach zwracają to samo odwołanie internowane, nie gwarantuje, że zwrócone odwołanie jest takie samo jak literał ciągu.
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.)
Pula intern może być używana przez środowisko uruchomieniowe do oszczędzania magazynu ciągów. Jednak automatyczne internowanie literałów ciągu nie jest gwarantowane — w zależności od tego, jak zestawienie zostało skompilowane i wykonane, niektóre literały mogą nie być dodane do puli.
W poniższym przykładzie ciąg s1 ma wartość "MyTest". 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. Jeśli s1 został już zainternowany (na przykład, ponieważ zestaw wymaga internowania literału ciągu), metoda zwraca to samo odwołanie co s1, które jest następnie przypisane do s3, oraz s1 i s3 porównują się jako równe. W przeciwnym razie zostanie utworzony nowy wpis zinternowany dla s2 i przypisany do s3, a s1 i s3 nie będą równe w porównaniu. W każdym z tych przypadków s1 i s2 są nierówne, ponieważ odnoszą się do różnych obiektów.
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.
Zagadnienia dotyczące wydajności
Jeśli próbujesz zmniejszyć łączną ilość pamięci przydzielanej przez aplikację, pamiętaj, że internowanie ciągu, czyli przechowywanie ich w jednej kopii w pamięci, 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 zainternowanego obiektu może utrzymywać się nawet po zakończeniu działania twojej aplikacji lub jej domeny aplikacyjnej. Po drugie, aby internować ciąg, musisz najpierw utworzyć ciąg. Pamięć używana przez obiekt String musi być nadal przydzielana, mimo że pamięć zostanie ostatecznie zebrana jako śmieci.
Członek wyliczenia CompilationRelaxations.NoStringInterning oznacza zestawienie jako niewymagające internowania literału ciągu. Domyślnie kompilator języka C# emituje CompilationRelaxationsAttribute z flagą NoStringInterning dla każdego modułu w celu uzyskania lepszej wydajności, co oznacza, że literały ciągów nie są gwarantowane do dodania do puli intern. Można dostosować komponent NoStringInterning przy użyciu atrybutu CompilationRelaxationsAttribute.
W przypadku publikowania aplikacji przy użyciu natywnej funkcji AOT wyłączenie NoStringInterning nie jest obsługiwane. W przypadku natywnej funkcji AOT literały ciągu nie mają gwarancji dodania do puli intern, więc Intern może nie znaleźć dopasowania dla ciągu, który wydaje się być literałem w kodzie źródłowym.