Преобразование С# int byte
Почему
byte someVar;
someVar -= 3;
действителен, но
byte someVar;
someVar = someVar - 3;
разве?
Ответы
Ответ 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 в любом случае, чтобы заставить оператора работать.
Они отразили проблему, компилятор автоматически издает приведение без вашей помощи.