Curioddity Number 4: how many strings do I have? [Kit George]

Curioddity Number 4: how many strings do I have? [Kit George]

  • Comments 8

Well its time for another curioddity. This one is pretty fun, there's a couple of good sidesteps involved. The following code is gong to write out 3 lines of code to the Console. Your tasks are to:

1: without running the code, write down what you think will be written out

2: run the code, and see for yourself what was written out

3: figure out, if 1 and 2 don't match, what the heck is going on!

using System.Text;

using System;

class intern

{

    static unsafe void ModifyConst() {

        string str1 = "Hello";

        fixed(char* pstr = str1) {

            pstr[0] = 'X';

        }

    }

    static void Main() {

        ModifyConst();

        StringBuilder sb = new StringBuilder("Hel");

        sb.Append("lo");

        string str = sb.ToString();

        Console.WriteLine(str);

        Console.WriteLine("Hello");

        switch(str) {

            case "Xello":

               Console.WriteLine("string is Xello"); break;

            case "Hello":

                Console.WriteLine("string is Hello"); break;

            default:

                Console.WriteLine("Not Found"); break;

        }

    }

}

  • Hello
    Xello
    Not Found

    Hello is first. The SB will put this string together without reference to the interned string.

    Xello second. The ModifyConst method changes the interned string. any literal instances of Hello are changed.

    Not Found Next. As per above, the case "Hello" which is interned will be changed by modifyconst to "Xello". As such, there is no match to the "Hello" string which is created by the SB.

    The name of the class was too good of a hint.
  • Using an Unsafe code block, ModifyConst() modifies the Const in memory to "Xello".

    The compiler is pretty smart, knowing that strings are immutable in .NET, reuses the memory for the literals defined in Main().

    The literal "Hello" in the following two lines of code from Main() are actually evaluated to "Xello". This can be seen in the IL.

    thus:
    Console.WriteLine("Hello");
    print "Xello"

    and
    switch(str)
    {
    case "Hello":

    is the same as comparing
    str = Modified Literal
    "Hello" = "Xello"

  • I've already learn that from
    http://blog.joycode.com/qqchen/archive/2004/08/23/31344.aspx

    They're so similar. And I wounder where this info originally came from? Could I learn more from there?

    :)
  • Sumtec, I put this code in my blog to demostrate the string interning and CLR's handling of switch/case. It doesn't come from any book or anything. Jeffrey Richter's "Applied Microsoft .NET Framework Programming" is the best reference book I can find on this topic.
  • Apologies if this originated elsewhere, and kudos to the originator, it's an excellent brain-twister.
  • Hi, Kit. There is no problem. I'm actually glad to see that there are people reading my blogs. :)
  • Maybe it is my fault.
    I orginally saw the materials in http://blog.joycode.com and told somebody in microsoft.

    And the answer is in switch case, str = "Hello" both compares with "Xello"
Page 1 of 1 (8 items)