问题描述
假设我有一个字符串“str”。我想使用 String.Intern 方法实习它。我只是想知道,如果 'str' 的值尚未被实习,那么 String.Intern 究竟是如何工作的。 documentation 中的方法描述如下:
Intern 方法使用 intern 池搜索等于的字符串 str 的值。如果这样的字符串存在,它在实习生中的引用 池返回。如果字符串不存在,对 str 的引用是 添加到实习生池中,然后返回该引用。
但是这本书的摘录“CLR via C#”却有不同的说法:
实习生,接受一个字符串,获取它的哈希码,并检查 匹配的内部哈希表。如果一个相同的字符串已经 存在,则返回对已经存在的 String 对象的引用。 如果不存在相同的字符串,则制作该字符串的副本, 副本被添加到内部哈希表中,并引用了这个 返回副本。
我猜文档中的描述是正确的。那么,在不复制字符串对象的情况下,只将 str 的引用添加到实习池中?
解决方法
这很容易直接测试:
// Make string from char[] to ensure it's not already interned
string s1 = new string(new[] { 'H','e','l','o' });
string i1 = string.Intern(s1);
bool result1 = object.ReferenceEquals(s1,i1);
string s2 = new string(new[] { 'H','o' });
string i2 = string.Intern(s2);
bool result2 = object.ReferenceEquals(s2,i2);
请注意,result1
设置为 true
,表示未复制原始 string
对象。另一方面,result2
设置为 false
,表明在实习池中找到了第二个构造的 string
对象 "Hello"
,因此 string.Intern()
方法返回该实习实例,而不是传入的新构造实例。
string.Intern()
方法不复制字符串。它只是检查传递的引用是否等于池中已有的字符串,如果不相等,则将其添加到池中。