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.