Search code examples
c#stringreferenceequals

Why string interned but has different references?


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

Console.WriteLine(string.IsInterned(s3));           // abc
Console.WriteLine(String.ReferenceEquals(s1, s3));  // False

I just cannot understand why s3 interned, but ReferenceEquals was False.

Dose they have two copies in intern pool?

Thanks in advance.


Solution

  • There are basically three different situations possible when string.IsInterned is invoked. To illustrate, here is a test method:

    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");
    }
    

    You can "hit" all three situations with this code:

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

    Output:

    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

    Since the literal "0" is mentioned in the program text, a string instance with value "0" will exist in the intern pool. The variable x is a reference to that instance.

    The variable y has the same value as x, but that is not computed until run-time (the C# compiler makes no guesses as to what int.ToString(IFormatProvider) could be returning). As a consequence, y is another instance than is x.

    The variable z has a value that is not found in the intern pool.