Подтвердить что ты не робот

Является ли оператор + = b из char таким же, как a = a + b?

Нашел интересную проблему: следующий код работает с другим результатом:

char c = 'a';

c += 'a';   //passed
c = c + 'a'; //Cannot implicitly convert type 'int' to 'char'. An explicit conversion exists (are you missing a cast?)

Есть ли разница между a += b и a=a+b, или просто проверка кода компилятора пропустила его?

Моя точка зрения, почему char += char может передавать проверку кода, а char = (char+char) считается char = int?

4b9b3361

Ответ 1

Спецификация С#, раздел 7.17.2 Составное назначение:

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

...

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

И это именно то, что мы имеем здесь. Тип возврата операции int, но типы x и y являются char, и поэтому для нас автоматически добавляется дополнительный листинг.

(Я считаю, что это правило существует, потому что вам нигде не нужно вставлять явное выделение, и это вроде как "ожидается", особенно в тех случаях, когда x и y являются одним и тем же типом)

Ответ 2

Во втором случае это присваивание, которое не выполняется, а не само вычисление. Если вы явно передали результат во второй строке в char, он отлично работает, и, действительно, следующие три строки генерируют идентичный IL:

    c += (char)1;
    c = (char)(c + (char)1);
    c = (char)(c + 1);

Так что да. Есть разница.

Обратите внимание, что в третьей строке я не стал набрасывать 1 на char, так как вычисление просто преобразует его обратно в int.

Ответ 3

Результирующий тип + = is char в этом случае, и результирующий тип c + (char) 1 является int.

Следующий код печатает:

o1 System.Char o2 System.Int32

    public static void Main(string[] args)
    {
        char c = 'a';

        object o1 = c += (char)1;
        object o2 = c + (char)1;

        WriteLine("o1 " + o1.GetType());
        WriteLine("o2 " + o2.GetType());
     }

Ответ 4

Чтобы дать ответ Damien в более простых выражениях:
Составные операторы (например, +=, -= и т.д.) автоматически приводят результат к целевому типу (если это возможно). Поэтому c += 'a' работает, потому что он оценивается как c = (char)(c + 'a').

В этом случае преобразование необходимо, поскольку возвращаемый тип арифметических операций между символами равен int (поэтому c = c + 'a' не компилируется, так как ему не хватает приведенного выше).