Why is the integer converted to string in this case?
Asked Answered
S

4

9

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?

Stansberry answered 2/5, 2012 at 13:55 Comment(0)
J
23

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.

Jepum answered 2/5, 2012 at 13:58 Comment(0)
E
18

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.

Enculturation answered 2/5, 2012 at 15:16 Comment(1)
I like your answer. But I'm not sure of the last part: if by spec u mean that the + operator is defined the way @brokenglass has mentioned, i'd agree...Stansberry
E
8

In both cases, you've got the + operator with the string as one of the operands. There are no overloaded user-defined operators involved, so the compiler will use both of those as string concatenation situations.

As far as I'm aware, the C# compiler will only not use string concatenation for a scenario of x + y where either x or y is a string expression at compile-time if there's a user-defined overload, e.g. the XName operator +(XNamespace, string) operator.

Emmie answered 2/5, 2012 at 13:57 Comment(0)
O
0

Actually the "+" operator is for concatenation. Making concatenation between an int and string will give a string (with automatically cast int to string)

Oldworld answered 2/5, 2012 at 14:4 Comment(1)
Using "+" between to numeric variables in Console.WriteLine will result in a sum of those to numeric variables in the output.Oldworld

© 2022 - 2024 — McMap. All rights reserved.