Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Poznámka:
Tento článek obsahuje doplňující poznámky k referenční dokumentaci pro toto rozhraní API.
Modul CLR (Common Language Runtime) udržuje tabulku s názvem intern pool, která obsahuje jeden odkaz pro každou jedinečnou řetězcovou hodnotu. Metoda Intern používá interní zásobník k vyhledání řetězce, který se rovná hodnotě str. Pokud takový řetězec neexistuje, přidá se do fondu odkaz str, a vrátí se tento odkaz. (Naproti tomu metoda IsInterned(String) vrátí odkaz null, pokud požadovaný řetězec neexistuje v interním fondu.)
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.