Так заложено в C # и, по сути, восходит к C / C ++ - последний также продвигает операнды до int
, вы просто обычно не замечаете, потому что int -> char
преобразование является неявным, а в C # его нет. . Это относится не только к |
, но и ко всем арифметическим и побитовым операндам - например, добавление двух byte
также даст вам int
. Я процитирую здесь соответствующую часть спецификации:
Двоичное числовое продвижение происходит для операндов предопределенных бинарных операторов +, -, *, /,%, &, |, ^, ==,! =,>, ‹,> = И‹ =. Двоичное числовое продвижение неявно преобразует оба операнда в общий тип, который в случае нереляционных операторов также становится типом результата операции. Двоичное числовое продвижение заключается в применении следующих правил в том порядке, в котором они указаны здесь:
Если один из операндов имеет тип decimal, другой операнд преобразуется в тип decimal, или возникает ошибка времени компиляции, если другой операнд имеет тип float или double.
В противном случае, если один из операндов имеет тип double, другой операнд преобразуется в тип double.
В противном случае, если один из операндов имеет тип float, другой операнд преобразуется в тип float.
В противном случае, если один из операндов имеет тип ulong, другой операнд преобразуется в тип ulong или возникает ошибка времени компиляции, если другой операнд имеет тип sbyte, short, int или long.
В противном случае, если один из операндов имеет тип long, другой операнд преобразуется в тип long.
В противном случае, если один из операндов имеет тип uint, а другой операнд имеет тип sbyte, short или int, оба операнда преобразуются в тип long.
В противном случае, если один из операндов имеет тип uint, другой операнд преобразуется в тип uint.
В противном случае оба операнда преобразуются в тип int.
Я не знаю точного объяснения этого, но могу придумать одно. Особенно для арифметических операторов может быть немного удивительно, если (byte)200 + (byte)100
внезапно станет равным 44
, даже если это имеет некоторый смысл, если внимательно рассмотреть задействованные типы. С другой стороны, int
обычно считается типом, который «достаточно хорош» для арифметических операций с большинством типичных чисел, поэтому, повышая оба аргумента до int
, вы получаете своего рода поведение «просто работает» для большинства распространенных случаев.
Что касается того, почему эта логика также применялась к побитовым операторам - я полагаю, это так в основном для согласованности. Это приводит к единому простому правилу, которое является общим для всех небулевых двоичных типов.
Но это все в основном догадки. Эрик Липперт, вероятно, будет тем, кто спросит об истинных мотивах этого решения для C #, по крайней мере (хотя было бы немного скучно, если бы ответ был просто «так это делается в C / C ++ и Java, и это достаточно хорошо. правило как таковое, поэтому мы не видели причин его менять »).
person
Pavel Minaev
schedule
31.07.2009