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

Преобразование С# int byte

Почему

byte someVar;
someVar -= 3; 

действителен, но

byte someVar;
someVar = someVar - 3;

разве?

4b9b3361

Ответ 1

Удивительно, но когда вы выполняете операции над байтами, вычисления будут выполняться с использованием значений int, при этом байты неявно отображаются в (int). Это справедливо и для short, а при выполнении арифметики с плавающей запятой аналогично float преобразуется до double.

Второй фрагмент эквивалентен:

byte someVar;
someVar = (int) someVar - 3;

Из-за этого вы должны вернуть результат обратно в (byte), чтобы заставить компилятор принять назначение.

someVar = (byte) (someVar - 3);

Ответ 2

Здесь копия таблицы в спецификации CLI (Ecma 335), которая указывает, какие операнды действительны для двоичных числовых операторов типа A op B, где A и B являются операндами, а "op" - это оператор, как Opcodes.Sub, который вы используете в своем фрагменте:

alt text

Для этого требуются некоторые аннотации:

  • "native int" - это IntPtr в программе С#
  • F представляет тип с плавающей точкой, double или float в С#
  • & представляет значение указателя, поля закрашены, потому что они являются небезопасными операциями
  • O представляет ссылку на объект
  • x - операция, которая не разрешена.

Обратите внимание на строку и столбец для F, оба операнда должны быть плавающей точкой, вы не можете напрямую добавить, скажем, int в double. Компилятор С# имеет дело с этим ограничением, автоматически преобразуя операнд int в double, чтобы оператор был действительным.

В зависимости от вашего вопроса: обратите внимание, что байтов, sbyte, char, short и ushort типов нет. В том же подходе компилятор преобразует операнды в наименьший тип, который может представлять значение, чтобы оператор мог использоваться. Который будет int32. Согласно таблице, результатом операции будет int32.

Теперь здесь rub: результат - int32, но для возврата к байтовому значению требуется сужение преобразования. От 32 бит до 8 бит. Эта проблема, потому что она теряет значительные бит. Компилятор С# требует, чтобы вы сделали это явным. Вы, по сути, признаете, что знаете, что делаете, и что знаете о потенциально удивительном результате. Как этот:

byte v = 255;
v = (byte)(v + 1);

Оператор - = является проблемой, потому что нет эффективного способа применить требуемый отбор. Это не выражается в синтаксисе языка. Использование (байт) 3 не имеет смысла, литерал преобразуется в int32 в любом случае, чтобы заставить оператора работать.

Они отразили проблему, компилятор автоматически издает приведение без вашей помощи.