С# числовые константы
У меня есть следующий код С#:
byte rule = 0;
...
rule = rule | 0x80;
который вызывает ошибку:
Невозможно неявно преобразовать тип 'int' в 'byte'. Явное преобразование существует (вы пропускаете листинг?)
[Обновление: первая версия вопроса была неправильной... Я неправильно прочитал вывод компилятора]
Добавление роли не выполняет:
rule = rule | (byte) 0x80;
Мне нужно записать его как:
rule |= 0x80;
Это просто странно. Почему оператор |=
не отличается от оператора |
?
Есть ли другой способ сообщить компилятору относиться к константе как к байту?
@Giovanni Galbo: да и нет. Код относится к программированию флэш-памяти во внешнем устройстве и логически представляет один байт памяти. Я мог бы наложить его позже, но это показалось более очевидным. Наверное, мое наследие C проявляется слишком много!
@Jonathon Holland: синтаксис "как" выглядит более аккуратным, но, к сожалению, он не работает... он производит:
Оператор as должен использоваться с ссылочным типом или типом с нулевым значением ('byte' - тип значения, не допускающего nullable)
Ответы
Ответ 1
int rule = 0;
rule |= 0x80;
http://msdn.microsoft.com/en-us/library/kxszd0kx.aspx The | оператор определен для всех типов значений. Я думаю, что это приведет к намеченному результату. Оператор "| =" является или присваивает оператор, который является просто сокращением для правила = правило | 0x80.
Одна из самых простых вещей о С# заключается в том, что она позволяет вам делать сумасшедшие вещи, такие как типы значений злоупотреблений, просто основанные на их размере. "Int" точно совпадает с байтом, за исключением того, что компилятор будет вызывать предупреждения, если вы попытаетесь использовать их как в одно и то же время. Просто придерживаться одного (в данном случае, int) работает хорошо. Если вас беспокоит 64-разрядная готовность, вы можете указать int32, но все int файлы int32, даже работающие в режиме x64.
Ответ 2
С# не имеет буквенного суффикса для байта. u = uint, l = long, ul = ulong, f = float, m = decimal, но не байт. Вы должны бросить его.
Ответ 3
Это работает:
rule = (byte)(rule | 0x80);
По-видимому, выражение 'rule | 0x80 'возвращает int, даже если вы определяете 0x80 как' const byte 0x80 '.
Ответ 4
Термин, который вы ищете, является "Literal" и, к сожалению, С# не имеет байтового литерала.
Вот список всех литералов С#.
Ответ 5
В соответствии с Спецификация ECMA, стр. 72, нет байтового литерала. Только целые литералы для типов: int, uint, long и ulong.
Ответ 6
Похоже, вам просто нужно сделать это уродливо: http://msdn.microsoft.com/en-us/library/5bdb6693.aspx.
Ответ 7
Почти пять лет спустя, и никто не ответил на этот вопрос.
Несколько ответов утверждают, что проблема заключается в отсутствии байтового литерала, но это не имеет значения. Если вы подсчитаете (byte1 | byte2)
, результат будет иметь тип int
. Даже если "b" был буквальным суффиксом для байта, тип (23b | 32b)
все равно был бы int
.
Принятые ответные ссылки на статью MSDN, утверждающие, что operator|
определяется для всех интегральных типов, но это также неверно.
operator|
не определен на byte
, поэтому компилятор использует свои обычные правила разрешения перегрузки, чтобы выбрать версию, определенную на int
. Следовательно, если вы хотите присвоить результат byte
, вам нужно его бросить:
rule = (byte)(rule | 0x80);
Вопрос остается, почему работает rule |= 0x80;
?
Поскольку спецификация С# имеет специальное правило для составного присвоения, которое позволяет опустить явное преобразование. В составном присваивании x op= y
правило:
если выбранный оператор является предопределенным оператором, если тип возврата выбранного оператора явно конвертируется в тип x, а если y неявно конвертируется в тип x или оператор является оператором сдвига, то операция оценивается как x = (T)(x op y)
, где T - тип x, за исключением того, что x оценивается только один раз.
Ответ 8
К сожалению, ваше единственное средство - это сделать так, как вы. Суффикса для обозначения литерала как байта нет. | оператор не обеспечивает неявное преобразование как назначение (т.е. инициализация).
Ответ 9
По-видимому, выражение 'rule | 0x80 'возвращает int, даже если вы определите 0x80 как 'const byte 0x80'.
Я думаю, что правило - это числа, такие как 0x80 по умолчанию для int, если вы не включите буквенный суффикс. Таким образом, для выражения rule | 0x80
результатом будет int, поскольку 0x80 является int и правило (которое является байтом) можно безопасно преобразовать в int.
Ответ 10
В соответствии со стандартом C байты ВСЕГДА продвигают к int в выражениях, даже константах. Однако до тех пор, пока оба значения НЕ ПОДКЛЮЧАЮТСЯ, старшие разряды будут отброшены, поэтому операция должна вернуть правильное значение.
Аналогично, поплавки продвигаются вдвое и т.д.
Вытащить копию K & R. Все это там.