String.Intern(String) 方法

定義

取得系統對指定 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

參數

str
String

一個在實習生池中搜尋的字串。

傳回

系統對 的參考 str(若被 interned);否則,則為值為 的字串 str的新參考。

例外狀況

strnull

範例

以下範例會產生兩個取值相等的字串,並展示將它們交替時會得到相同的參考。

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

備註

![註] > 雖然 String.Intern 保證兩個值相等的字串會回傳相同的intern-reference,但並不保證回傳的reference與字串的字面值相同。

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

執行時可利用intern pool來節省字串儲存空間。 然而,字串字面值的自動間存並非保證——根據組合語言的編譯與執行方式,有些字面值可能不會被加入池中。

以下範例中,字串 s1 的值為「MyTest」。 類別 System.Text.StringBuilder 會產生新的字串物件,其值與 s1相同。 這個字串的參考會指派給 s2。 方法 Intern 會搜尋與 具有相同值的 s2字串。 如果 s1 已經被 interned 了(例如,因為組合需要字串字面 interning),該方法會回傳與 s1相同的參考,然後指派給 s3、 和 s1 ,且 s3 比較相等。 否則,會為 s2 建立一個新的 interned 條目,並指派給 s3,而 s1s3 比較不相等。 無論哪種情況, s1 並且 s2 因為指的是不同的對象而比較不平等。

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.

效能考量

如果您嘗試減少應用程式配置的記憶體總量,請記住,插入字串有兩個不必要的副作用。 首先,分配給內部化 String 對象的記憶體在 Common Language Runtime(CLR)終止之前不太可能被釋放。 原因是 CLR 對內部化 String 對象的引用,即使在您的應用程式甚至應用程式域終止之後,也可以持續存在。 其次,若要將字串實化,您必須先建立字串。 物件所使用的 String 記憶體仍必須配置,即使記憶體最終會被垃圾收集也一樣。

列舉成員會將 CompilationRelaxations.NoStringInterning 組件標示為不需要字串常值實例化。 預設情況下,C# 編譯器會在每個組件中使用CompilationRelaxationsAttribute並設置NoStringInterning標誌以提升效能,這表示字串不一定會被加入重用池。 你可以在元件上使用NoStringInterning屬性自訂CompilationRelaxationsAttribute

當你用 原生 AOT 發佈應用程式時, NoStringInterning 關閉功能就不支援。 原生 AOT 的字串常值不保證會被加入 intern 池,所以 Intern 可能無法匹配在原始碼中看似字面常值的字串。

適用於

另請參閱