共用方式為


System.String.Intern 方法

本文提供此 API 參考文件的補充備註。

Common Language Runtime 藉由維護稱為 「內部存放區」的表格來節省字串儲存空間,該表格包含在程式中宣告或建立的每個唯一字面字串的單一參考。 因此,具有特定值的常值字串實例只存在於系統中一次。 例如,如果您將相同的常值字串指派給數個變數,運行時間會從實習生集區擷取對常值字串的相同參考,並將它指派給每個變數。

方法 Intern 會使用實習生集區來搜尋等於其參數值的字串, str。 如果存在這類字串,則會傳回其在實習生集區中的參考。 如果字串不存在,則會將str的參考新增至字串內部池,然後傳回該參考。 (相反地,如果要求字串不存在於實習生集區中, IsInterned(String) 此方法會傳回 Null 參考。

在下列範例中,具有「MyTest」值的字串 s1 已經被實體化,因為它是程式中的文字常數。 類別 System.Text.StringBuilder 會產生新的字串物件,其值與 s1相同。 這個字串的參考會指派給 s2。 方法 Intern 會搜尋與 具有相同值的 s2字串。 由於這類字串存在,因此方法會傳回指派給 s1的相同參考。 然後,該參考會指派給 s3。 參考 s1s2 比較不相等,因為它們參考不同的物件;參考 s1s3 比較相等,因為它們參考相同的字串。

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 組件標示為不需要字串常值實例化。 您可以將 NoStringInterning 套用至組件,使用CompilationRelaxationsAttribute屬性。 另外,當你用 Ngen.exe(原生影像產生器) 在執行前編譯組合語言時,字串不會跨模組內嵌。