string s1 = "abc";
string s2 = "ab";
string s3 = s2 + "c";
Console.WriteLine(string.IsInterned(s3)); // abc
Console.WriteLine(String.ReferenceEquals(s1, s3)); // False
我无法理解为什么s3实习,但ReferenceEquals
是假的。
他们在实习池中有两份副本?
提前致谢。
答案 0 :(得分:6)
它们是单独的参考。字符串"abc"
是实习的,因为它是一个文字字符串。
表达式s2 + "c"
被编译为string.Concat(s2, "c")
..这会产生一个新的(和单独的)字符串引用。
答案 1 :(得分:3)
这是因为虽然该字符串的值确实被实现(因为文字“abc”),但它与实习字符串不是同一个实例,而是由+运算符生成的实例。
String.ReferenceEquals(s1, string.IsInterned(s3));
会返回true
答案 2 :(得分:0)
调用string.IsInterned
时,基本上有三种不同的情况。为了说明,这是一种测试方法:
static void MyInternCheck(string str)
{
var test = string.IsInterned(str);
if ((object)test == (object)str)
Console.WriteLine("Yes, your string instance is in the intern pool");
else if (test == str)
Console.WriteLine("An instance with the same value exists in the intern pool, but you have a different instance with that value");
else if (test == null)
Console.WriteLine("No instance with that value exists in the intern pool");
else
throw new Exception("Unexpected intern pool answer");
}
你可以"击中"使用此代码的所有三种情况:
static void Main()
{
string x = "0";
MyInternCheck(x);
string y = (0).ToString(CultureInfo.InvariantCulture);
MyInternCheck(y);
string z = (1).ToString(CultureInfo.InvariantCulture);
MyInternCheck(z);
}
输出:
Yes, your string instance is in the intern pool An instance with the same value exists in the intern pool, but you have a different instance with that value No instance with that value exists in the intern pool
由于程序文本中提到了文字"0"
,因此实习池中将存在值为"0"
的字符串实例。变量x
是对该实例的引用。
变量y
与x
具有相同的值,但是直到运行时才计算出来(C#编译器没有猜测{{1}可能正在返回)。因此,int.ToString(IFormatProvider)
是另一个实例,而不是y
。
变量x
具有在实习池中找不到的值。