String.Intern(String) Metod

Definition

Hämtar systemets referens till den angivna String.

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

Parametrar

str
String

En sträng att söka efter i internpoolen.

Returer

Systemets referens till str, om den är internerad, annars en ny referens till en sträng med värdet str.

Undantag

str är null.

Exempel

I följande exempel skapas två strängar med samma värden och visar att internering av dem ger samma referens.

// 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
'

Kommentarer

! [OBS] > Även om String.Intern garanterar att två strängar med samma värden returnerar samma internerade referens, garanterar det inte att den returnerade referensen är samma som en strängliteral.

        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.)

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.

Gäller för

Se även