Симптом
Следующий код компилируется в C ++, но отклоняется компилятором C # с несовместимостью типов отчетов третьей строки.
ulong mut = 5;
ulong mut3 = 6;
byte foo = (mut & 0xFF) ^ (mut3 & 0xFF);
Объяснение
Выражение (mut & 0xFF) ^ (mut3 & 0xFF)
имеет тип ulong
и не может быть присвоено переменной типа byte
.
Переменная mut
представляет собой ulong
. Все перегрузки &
требуют симметрии типа операнда, поэтому в выражении (mut & 0xFF)
значение 0xFF
повышается до ulong
, а результат операции имеет тип ulong
.
Хотя аналогичный процесс также дает второму подвыражению тип ulong
, это является случайным, поскольку в большем выражении A ^ B
тот факт, что выражение A
имеет тип ulong
, вызовет выражение B
будет повышен.
Таким образом, выражение (mut & 0xFF) ^ (mut3 & 0xFF)
имеет тип ulong
и требует явного приведения, прежде чем его можно будет присвоить переменной типа byte
.
Решение
Явно типизируйте все выражение перед присваиванием.
Примечания
Люди отключают предупреждения вместо того, чтобы думать о них, потому что большинство библиотек C + изобилуют дефектами. Если вы снова включите предупреждения, вы получите так много, что бесполезно пытаться пробраться через них, даже если где-то в этой неразберихе появится примечание о том, что «требуется неявный тип передачи с потерями».
Если вы прочитаете спецификацию языка C #, особенно с учетом операторов, вы узнаете много полезного. Например, этот код не будет работать:
byte b = 0xF0 | 0x0E; //b should contain 0xFE
но это удастся:
byte b1 = (byte)(0xF0 | 0x0E); //typecast fixes it
byte b2 = 0xF0;
b2 |= 0x0E; //reflexive operator typed by target variable