Kommentar
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Anmärkning
Den här artikeln innehåller ytterligare kommentarer till referensdokumentationen för det här API:et.
Den vanliga språkkörningen underhåller en tabell, kallad internpoolen, som innehåller en enda referens för varje unikt strängvärde. Metoden Intern använder internpoolen för att söka efter en sträng som är lika med värdet av str. Om det inte finns någon sådan sträng läggs en referens till str i poolen och den referensen returneras. (Metoden returnerar däremot IsInterned(String) en null-referens om den begärda strängen inte finns i internpoolen.)
Internpoolen kan användas av körtiden för att spara stränglagringsutrymme. Automatisk internering av strängliteraler garanteras dock inte, beroende på hur sammansättningen kompilerades och kördes kanske vissa literaler inte läggs till i poolen.
I följande exempel har strängen s1 värdet "MyTest". Klassen System.Text.StringBuilder genererar ett nytt strängobjekt som har samma värde som s1. En referens till den där strängen tilldelas s2. Metoden Intern söker efter en sträng som har samma värde som s2. Om s1 redan har internerats (till exempel eftersom assemblyn kräver strängliteral internering) returnerar metoden samma referens som s1, som sedan tilldelas till s3, och s1 och s3 är lika vid jämförelse. I annat fall skapas en ny intern post för s2 och tilldelas till s3, och s1 och s3 är inte likvärdiga vid jämförelse. I båda fallen s1 och s2 är olika eftersom de refererar till olika objekt.
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.
Prestandaöverväganden
Om du försöker minska den totala mängden minne som programmet allokerar bör du tänka på att internering av en sträng har två oönskade biverkningar. För det första kommer det minne som allokerats för internerade String objekt sannolikt inte att släppas förrän CLR (Common Language Runtime) avslutas. Anledningen är att CLR:s referens till det internerade String objektet kan bevaras när programmet, eller till och med programdomänen, har avslutats. För det andra, för att kunna internalisera en sträng, måste du först skapa strängen. Det minne som används av String objektet måste fortfarande allokeras, även om minnet så småningom kommer att vara skräpinsamling.
Uppräkningsmedlemmen CompilationRelaxations.NoStringInterning markerar en sammansättning som inte kräver strängliteral internering. Som standardinställning genererar C#-kompilatorn en CompilationRelaxationsAttribute med NoStringInterning-flaggan på varje assembly för bättre prestanda, vilket innebär att strängliteraler kanske inte läggs till i internpoolen. Du kan anpassa NoStringInterning på en sammansättning med hjälp av attributet CompilationRelaxationsAttribute .
När du publicerar en app med inbyggd AOT stöds inte avstängning NoStringInterning . Med inbyggd AOT är strängliteraler inte garanterade att läggas till i internpoolen, så Intern kanske inte hittar någon matchning för en sträng som verkar vara en literal i källkoden.