公共语言运行库通过维护一个表来存放字符串,该表称为拘留池,它包含程序中以编程方式声明或创建的每个唯一的字符串的一个引用。因此,具有特定值的字符串的实例在系统中只有一个。
例如,如果将同一字符串分配给几个变量,运行库就会从拘留池中检索对该字符串的相同引用,并将它分配给各个变量。
Intern 方法使用拘留池来搜索与 str 值相等的字符串。如果存在这样的字符串,则返回拘留池中它的引用。如果不存在,则向拘留池添加对 str 的引用,然后返回该引用。
在下面的 C# 示例中,值为“MyTest”的字符串 s1 已经留用,因为它在程序中是一个字符串常量。
System.Text.StringBuilder 类生成与 s1 同值的新字符串对象。对该字符串的引用被分配给 s2。
Intern 方法搜索与 s2 具有相同值的字符串。由于存在这样的字符串,该方法会返回分配给 s1 的同一引用,然后将该引用分配给 s3。
引用 s1 和 s2 的比较结果是不相等的,这是因为它们引用的是不同的对象;而引用 s1 和 s3 的比较结果是相等的,因为它们引用的是相同的字符串。
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.
将此方法与 IsInterned 方法进行比较。
版本注意事项
从 .NET Framework 2.0 版开始,对 Intern 方法的行为进行了更改。在下面的 C# 代码序列中,对 Empty 的引用被分配给变量 str1,对 Intern 方法返回的 Empty 的引用被分配给变量 str2,然后比较 str1 和 str2 中包含的引用是否相等。
string str1 = String.Empty; string str2 = String.Intern(String.Empty); if ((object) str1) == ((object) str2) …
在 .NET Framework 1.1 版中,str1 和 str2 不相等,但从 .NET Framework 2.0 版开始,str1 和 str2 相等。
性能注意事项
如果要减少应用程序分配的内存总量,请记住留用字符串有两个不希望出现的副作用。首先,为留用的 String 对象分配的内存在公共语言运行库 (CLR) 终止之前不大可能释放。这是因为 CLR 对留用的 String 对象的引用可能保持到应用程序终止之后,甚至可能保持到应用程序域终止之后。其次,要留用字符串,必须先创建字符串。即使 String 对象使用的内存最终将通过垃圾回收,仍然必须分配该内存。