2012-05-02 2 views
9

Что происходит внизу?Почему целое число, преобразованное в строку в этом случае?

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 преобразуется в строку в обоих случаях. Я сбиваю с толку идею о приоритете оператора (хотя этот пример не показывает много чего) и направление оценки. Иногда оценка происходит от слева направо или наоборот. Я точно не знаю науку о том, как оценивается выражение ...

Почему i преобразован в строку в приведенном выше примере, а не дает ошибку компиляции?

ответ

23

От С # спецификации - раздел 7.7.4 Добавление оператора:

Объединение строк:

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

Бинарный оператор + выполняет конкатенацию, когда один или оба операнды строки типа. Если операнд конкатенации строк равен , то пустая строка заменяется. В противном случае любой аргумент non-string преобразуется в его строковое представление, вызывая виртуальный метод ToString , унаследованный от объекта типа. Если ToString возвращает null, заменяется пустая строка.

+2

Спасибо - не удалось быстро получить спецификацию :) –

8

В обоих случаях у вас есть оператор + со строкой как один из операндов. Не существует перегруженных определяемых пользователем операторов, поэтому компилятор будет использовать как, так и в качестве ситуаций конкатенации строк.

Насколько я знаю, компилятор С # только не будет использовать конкатенацию для сценария x + y где либоx или y является string выражением во время компиляции, если есть определенный пользователь перегрузка, например, Оператор XName operator +(XNamespace, string).

0

Фактически оператор «+» предназначен для конкатенации. Создание конкатенации между int и string даст строку (с автоматическим литьем int в строку)

+0

Использование «+» между числовыми переменными в Console.WriteLine приведет к сумме этих чисел к числовым переменным в выходе. – SoEnLion

18

Я сбиваю с толку идею направления приоритета и оценки оператора.

Нет, вы не являетесь. Это часто путают, да, но это не то, что вы вводите в заблуждение, потому что ни приоритет, ни порядок оценки не являются релевантными на вопрос о том, преобразуется ли целое число в строку или почему законно добавлять целое число в строка.

К первому unconfuse вас на момент вы утверждаете, следует путать с, правила довольно просты:

  • выражения в скобки в соответствии с оператором старшинства и ассоциативности.
  • подвыражения оцениваются в порядке слева направо.

Это все, что вам нужно знать, чтобы все было правильно. Пусть Q() возвращает объект, который имеет индексатор с установщиком, и другие методами все возвращают целые числа:

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

То есть Скобки согласно старшинству и ассоциативности:

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

И теперь каждому подвыражение оценивается слева направо. Каждое подвыражение, включая подвыражения, которые сами имеют подвыражения. Так что это эквивалентно программе:

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; 

и, наконец, установщик индекса на q вызывается с индексом r и значением t3.

Обратите внимание: каждое подвыражение влево оценивается перед каждым подвыражением вправо. A() * B() осталось от C()/D(), так что бывает первым.

Это не имеет никакого отношения к вашему вопросу. Ваш вопрос основан на недоразумении.

Я хочу знать, почему я преобразуется в строку в приведенном выше примере, а на самом деле не дает ошибку компиляции

Там ваше недоразумение. i является не преобразовывается в строку. Он преобразуется в object. Ваша программа в точности эквивалентно:

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); 

Как вы можете видеть, нет никакого преобразования из i в строку, в первую очередь. i преобразуется в объект посредством преобразования бокса, а затем передается методу String.Concat. Затем этот метод вызывает object.ToString() по целому числу в штучной упаковке.

Так что дело с первой половины:

Я хочу знать, почему я преобразуется в строку в приведенном выше примере, а на самом деле не дает ошибку компиляции

Вторая половина is: почему нет ошибки компиляции?

Зачем возникла ошибка компиляции? Спецификация C# говорит, что вы можете добавить любую строку к любому объекту или любому объекту в любую строку. Int - это объект, и поэтому вы можете добавить его в строку.

+0

Мне нравится ваш ответ. Но я не уверен в последней части: если по spec u означает, что оператор + задан так, как сказал @brokenglass, я бы согласился ... – deostroll