That’s just wrong!

The C# compiler will convert expressions that use the “+” operator on strings into calls to the string.Concat function. So, for example, in this code:

    string a = "hello, ";
    string b = "world";
    string s = a + b;

The compiler changes the last line to the equivalent of:

    string s = string.Concat(a, b);

Seems reasonable, right?

Consider also Console.WriteLine, which treats its arguments as objects, and calls ToString on them. So this code:

    int a = 10;
    int b = 27;
    Console.WriteLine(a + b);

Gets converted to the equivalent of:

    int temp = a + b;
    Console.WriteLine(temp.ToString());

So what happens when you write this?

    Console.WriteLine(a + b + "foo");

You probably won’t be surprised to see the output “37foo”.

How about this one?

    Console.WriteLine(a + (b + "foo"));

The result? “1027foo”!!

So how does that work? The compiler converted that code to:

    string s = String.Concat(a, b, "foo");
    Console.WriteLine(s);

You see, there are String.Concat overloads that treat the arguments as type object. Those methods just call ToString on each argument, and concatenate the results.

That was pretty surprising. Consider this:

    int a = 10;
    int b = 27;
    string s1 = a + b;  // error: can't convert int to string
    string s2 = (a + b) + "foo"; // no problem, "37foo"
    string s3 = a + (b + "foo"); // no problem, "1027foo"

I understand why this happens. I don’t understand why the compiler writers thought it was a good thing. It leads to some very confusing results:

    int m = 10;
    object o = new object();
    string f = "foo";
    var s1 = m + o + f; // error: cannot apply operator "+" to types int and object
    var s2 = m + f + o; // hey, no problem.

That’s just wrong. It’s logically consistent, once you understand the logic. But it’s pretty darned confusing when you first look at it.