Прошло почти пять лет, и на самом деле никто не ответил на вопрос.
В нескольких ответах утверждается, что проблема заключается в отсутствии байтового литерала, но это не имеет значения. Если вы вычисляете (byte1 | byte2)
, результат будет иметь тип int
. Даже если бы «b» было буквальным суффиксом для байта, тип (23b | 32b)
все равно был бы int
.
Принятый ответ ссылается на статью MSDN, в которой утверждается, что operator|
определен для всех целочисленных типов, но это также не так.
operator|
не определено в byte
, поэтому компилятор использует свои обычные правила разрешения перегрузки, чтобы выбрать версию, определенную в int
. Следовательно, если вы хотите присвоить результат byte
, вам нужно привести его:
rule = (byte)(rule | 0x80);
Остается вопрос, почему rule |= 0x80;
работает?
Поскольку в спецификации C # есть специальное правило для составного присваивания, которое позволяет вам пропустить явное преобразование. В составном присваивании x op= y
правило:
если выбранный оператор является предопределенным оператором, если тип возвращаемого значения выбранного оператора явно преобразуется в тип x, и если y неявно преобразуется в тип x, или оператор является оператором сдвига, тогда операция оценивается как x = (T)(x op y)
, где T - это тип x, за исключением того, что x вычисляется только один раз.