String.Intern(String) Metoda
Definice
Důležité
Některé informace platí pro předběžně vydaný produkt, který se může zásadně změnit, než ho výrobce nebo autor vydá. Microsoft neposkytuje žádné záruky, výslovné ani předpokládané, týkající se zde uváděných informací.
Načte odkaz systému na zadanou Stringhodnotu .
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
Řetězec, který chcete vyhledat ve fondu internů.
Návraty
Odkaz systému na str, pokud je interná; v opačném případě nový odkaz na řetězec s hodnotou str.
Výjimky
str je null.
Příklady
Následující příklad vytvoří dva řetězce se stejnými hodnotami a ukazuje, že jejich prokládání přináší stejný odkaz.
// 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
'
Poznámky
! [POZNÁMKA] > I když
String.Internzaručuje, že dva řetězce se stejnými hodnotami vrátí stejný interovaný odkaz, nezaručuje, že vrácený odkaz je stejný jako řetězcový literál.
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.)
Fond internů může modul runtime použít k zachování úložiště řetězců. Automatické internování řetězcových literálů však není vždy zaručeno – v závislosti na tom, jak bylo sestavení zkompilováno a spuštěno, nemusí být některé literály přidány do zásobníku.
V následujícím příkladu má řetězec s1 hodnotu "MyTest". Třída System.Text.StringBuilder vygeneruje nový objekt řetězce, který má stejnou hodnotu jako s1. Odkaz na tento řetězec je přiřazen k s2. Metoda Intern vyhledá řetězec, který má stejnou hodnotu jako s2. Pokud s1 již byl internován (například protože sestavení vyžaduje internování řetězcového literálu), metoda vrátí stejný odkaz jako s1, který je pak přiřazen s3, a s1 a s3 porovnávají stejně. V opačném případě se vytvoří nová uložená položka pro s2 a přiřadí se s3, a s1 a s3 nejsou rovny. V obou případech, s1 a s2 se porovnávají jako nerovné, protože odkazují na různé objekty.
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.
Důležité informace o výkonu
Pokud se pokoušíte snížit celkovou velikost paměti, kterou aplikace přidělí, mějte na paměti, že prokládání řetězce má dva nežádoucí vedlejší účinky. Nejprve, paměť přidělená pro interované String objekty pravděpodobně nebude vydána, dokud CLR (Common Language Runtime) neukončí. Důvodem je, že odkaz CLR na interovaný String objekt může přetrvat i po ukončení vaší aplikace nebo dokonce domény aplikace. Za druhé, pokud chcete internovat řetězec, musíte nejprve vytvořit řetězec. Paměť využívaná objektu String musí být stále přidělena, i přesto že bude nakonec uvolněna procesem garbage collection.
Člen CompilationRelaxations.NoStringInterning výčtu označí sestavení jako nevyžadující prolínání řetězcového literálu. Kompilátor jazyka C# ve výchozím nastavení generuje CompilationRelaxationsAttribute spolu s příznakem NoStringInterning pro každé sestavení pro lepší výkon, což znamená, že není zaručeno přidání řetězcových literálů do fondu internů. Pomocí atributu NoStringInterning můžete přizpůsobit CompilationRelaxationsAttribute sestavení.
Když publikujete aplikaci pomocí nativní AOT, vypnutí NoStringInterning se nepodporuje. U nativních AOT není zaručeno, že se řetězcové literály přidají k internímu fondu, takže Intern nemusí najít shodu s řetězcem, který se zdá být literálem ve zdrojovém kódu.