为什么字符串实习但有不同的引用?

Lei*_*Kan 5 c# string referenceequals

string s1 = "abc";
string s2 = "ab";
string s3 = s2 + "c";

Console.WriteLine(string.IsInterned(s3));           // abc
Console.WriteLine(String.ReferenceEquals(s1, s3));  // False
Run Code Online (Sandbox Code Playgroud)

我只是不明白为什么s3实习,但是ReferenceEquals是假的.

他们在实习池中有两份副本吗?

提前致谢.

Sim*_*ead 6

它们是单独的参考.该字符串"abc"是interned,因为它是一个文字字符串.

表达式s2 + "c"被编译为string.Concat(s2, "c")..这导致一个新的(和单独的)字符串引用.


Jep*_*sen 1

基本上有三种不同的情况可能发生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");
}
Run Code Online (Sandbox Code Playgroud)

您可以使用以下代码“解决”所有三种情况:

static void Main()
{
  string x = "0";
  MyInternCheck(x);
  string y = (0).ToString(CultureInfo.InvariantCulture);
  MyInternCheck(y);
  string z = (1).ToString(CultureInfo.InvariantCulture);
  MyInternCheck(z);
}
Run Code Online (Sandbox Code Playgroud)

输出:

是的,您的字符串实例位于实习生池中
实习池中存在具有相同值的实例,但您有一个具有该值的不同实例
实习生池中不存在具有该值的实例

"0"由于程序文本中提到了文字,因此"0"实习池中将存在一个具有值的字符串实例。该变量x是对该实例的引用。

该变量与y具有相同的x,但直到运行时才计算该值(C# 编译器不会猜测可能int.ToString(IFormatProvider)返回的内容)。因此,y是 的另一个实例,而不是x

该变量z具有在实习池中找不到的值。