Search code examples
c#.netstring-interning

Does String.Intern method just add a reference to a string to the intern pool or it creates a copy of the string?


Suppose I have a string 'str'. I want to intern it using String.Intern method. I just wonder, how exactly String.Intern works in case when value of 'str' hasn't been interned yet. The description of the method from documentation is following:

The Intern method uses the intern pool to search for a string equal to the value of str. If such a string exists, its reference in the intern pool is returned. If the string does not exist, a reference to str is added to the intern pool, then that reference is returned.

But this excerpt from a book "CLR via C#" tells differently:

Intern, takes a String, obtains a hash code for it, and checks the internal hash table for a match. If an identical string already exists, a reference to the already existing String object is returned. If an identical string doesn’t exist, a copy of the string is made, the copy is added to the internal hash table, and a reference to this copy is returned.

I guess a description from the documentation is correct. So, only a reference to str is added to the intern pool without copying string object?


Solution

  • This is easy enough to test directly:

    // Make string from char[] to ensure it's not already interned
    string s1 = new string(new[] { 'H', 'e', 'l', 'l', 'o' });
    string i1 = string.Intern(s1);
    bool result1 = object.ReferenceEquals(s1, i1);
    
    string s2 = new string(new[] { 'H', 'e', 'l', 'l', 'o' });
    string i2 = string.Intern(s2);
    bool result2 = object.ReferenceEquals(s2, i2);
    

    Note that result1 is set to true, showing that the original string object is not copied. On the other hand, result2 is set to false, showing that the second constructed string object "Hello" was found in the intern pool, and so the string.Intern() method returns that interned instance instead of the newly constructed instance passed in.

    The string.Intern() method does not copy strings. It just checks whether the reference passed is equal to a string already in the pool, and adds it to the pool if it's not.