Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is the integer converted to string in this case?

What is happening below?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

public class DotNetPad
{
    public static void Main(string[] args)
    {
        int i = 10;
        string k = "Test";
        Console.WriteLine(i+k);
        Console.WriteLine(k+i);
    }
}

i is being converted to string in both cases. I am confusing myself with the idea of operator precedence (although this example doesn't show much of that) and evaluation direction. Sometimes evaluation happens from left-to-right or vice versa. I don't exactly know the science of how the expression is evaluated...

Why is i converted to string in the above example, and not actually giving a compilation error?

like image 272
deostroll Avatar asked May 02 '12 13:05

deostroll


2 Answers

From the C# spec - section 7.7.4 Addition operator:

String concatenation:

string operator +(string x, string y);
string operator +(string x, object y);
string operator +(object x, string y);

The binary + operator performs string concatenation when one or both operands are of type string. If an operand of string concatenation is null, an empty string is substituted. Otherwise, any non-string argument is converted to its string representation by invoking the virtual ToString method inherited from type object. If ToString returns null, an empty string is substituted.

like image 180
BrokenGlass Avatar answered Sep 28 '22 12:09

BrokenGlass


I am confusing myself with the idea of operator precedence and evaluation direction.

No, you are not. That is frequently confused, yes, but that is not the thing you are confusing because neither precedence nor order of evaluation is relevant to the question of whether the integer is converted to a string, or why it is legal to add an integer to a string.

To first unconfuse you on the point you claim to be confused on, the rules are quite simple:

  • expressions are parenthesized according to operator precedence and associativity.
  • subexpressions are evaluated in left-to-right order.

That's all you need to know to get it right. Suppose Q() returns an object that has an indexer with a setter, and the other methods all return integers:

Q()[R()] = A() * B() + C() / D();

That is parenthesized according to precedence and associativity:

Q()[R()] = ( ( A() * B() ) + ( C() / D() ) );

And now every subexpression is evaluated left-to-right. Every subexpression, including subexpressions that themselves have subexpressions. So this is equivalent to the program:

var q = Q(); 
var r = R(); 
var a = A(); 
var b = B(); 
var t1 = a * b; 
var c = C();
var d = D();
var t2 = c / d;
var t3 = t1 + t2;

and finally the index setter on q is called with index r and value t3.

Notice that every subexpression to the left is evaluated before every subexpression to the right. A() * B() is left of C() / D(), so it happens first.

This has nothing whatsoever to do with your question. Your question is based on a misunderstanding.

I want to know why i is converted to string in the above example, and not actually giving a compilation error

There's your misunderstanding. i is not being converted to string. It is being converted to object. Your program is exactly equivalent to:

   int i = 10;
   string k = "Test";
   string t1 = System.String.Concat((object)i, (string)k);
   Console.WriteLine(t1);
   string t2 = System.String.Concat((string)k, (object)i);
   Console.WriteLine(t2);

As you can see, there is no conversion from i to string in the first place. i is converted to object via a boxing conversion and then passed to the String.Concat method. That method then calls object.ToString() on the boxed integer.

So that deals with the first half of:

I want to know why i is converted to string in the above example, and not actually giving a compilation error

The second half is: why is there no compilation error?

Why should there be a compilation error? The C# specification says that you can add any string to any object, or any object to any string. An int is an object, and therefore you can add it to a string.

like image 24
Eric Lippert Avatar answered Sep 28 '22 11:09

Eric Lippert