О неявном преобразовании типа 'int' в 'char', почему он отличается между 's [i] + = s [j]' и 's [i] = s [i] +s [j]'

Пример кода для демонстрации:

public void ReverseString(char[] s) {
  for(int i = 0, j = s.Length-1; i < j; i++, j--){
        //s[i] = s[i]+s[j]; //<-- error           
        s[i] += s[j];       //<-- ok 

        s[j] = (char)(s[i] - s[j]); //<-- cast
        s[i] -= s[j];
    }
}

Как и в приведенном выше фрагменте кода, в то время как s[i] += s[j] работает без ошибок. Его эквивалентное утверждение s[i] = s[i]+s[j] вызовет ошибку следующим образом

ошибка CS0266: невозможно неявное преобразование типа int в char. Существует явное преобразование (вам не хватает приведения?

У меня вопрос в чем их разница и почему. Заранее спасибо.

Ответы

Ответ 1

Его эквивалентное утверждение s[i] = s[i]+s[j] вызовет ошибку следующим образом

Это не эквивалентное утверждение, хотя я могу понять, почему вы этого ожидаете. Из раздела 12.18.3 стандарта С# 5 ECMA, касающегося составного назначения:

Операция вида x op= y обрабатывается путем применения разрешения перегрузки бинарного оператора (§12.4.5), как если бы операция была записана x op y. Затем,

  • Если возвращаемый тип выбранного оператора неявно преобразуется в тип x, операция оценивается как x = x op y, за исключением того, что x вычисляется только один раз.
  • В противном случае, если выбранный оператор является предопределенным оператором, если тип возвращаемого значения выбранного оператора явно преобразуется в тип x, и если y неявно преобразуется в тип x или оператор является оператором сдвига, тогда операция оценивается как x = (T)(x op y), где T - это тип x, за исключением того, что x оценивается только один раз.

Эта вторая пуля - вот что здесь происходит. Там нет оператора для сложения значений char вместе - есть оператор int +(int, int), который выбран, и есть явное преобразование из int в char.

Итак, это:

s[i] += s[j];

более эквивалентно

s[i] = (char) (s[i] + s[j]);

... который прекрасно компилируется.