Это тот способ, с помощью конструкции в C#, и, по сути, восходит вплоть до C/C++ - последний также способствует операнды int
, вы обычно не замечаете, потому что преобразование int -> char
неявно, а не в C#. Это относится не только к |
, но и ко всем арифметическим и побитовым операндам - например, добавив два byte
s, вы получите int
. Я процитирую соответствующую часть спецификации здесь:
Binary числовое расширение происходит за операнды предопределенный +, -, *, /,%, &, |, ^, ==,! =,>, <,> =, и < = двоичные операторы. Двоичный числовое продвижение неявно преобразует оба операнда в общий тип, который, в случае нереляционных операторов , также становится результатом типа операции. Binary числовой продвижения состоит из применения следующих правил, в порядке их появляются здесь:
Если один из операндов имеют типа десятичного знака, то другой операнд преобразуется к типу десятичного или компиляций -time-ошибка возникает, если другой операнд имеет тип float или double.
В противном случае, если один из операндов имеет значение , тип double, другой операнд преобразован в тип double.
В противном случае, , если один из операндов имеет тип поплавка, другой операнд преобразуется к типу поплавок.
В противном случае, если один из операндов имеет тип ULONG, то другой операнд преобразуется в тип ULong или ошибка времени компиляции происходит, если другой операнд имеет тип SByte, короткий, INT, или длинный.
В противном случае, если либо операнд имеет длинный тип, другой операнд преобразуется в длинный.
В противном случае, если один из операндов имеет типа UINT, а другой операнд имеет тип SByte, короткий или междунар оба операнды преобразуются к типу долго.
В противном случае, если один из операндов имеет тип uint, другой операнд преобразован в тип uint.
В противном случае оба операнда преобразуются в тип int.
Я не знаю точное обоснование для этого, но я могу думать об одном. В частности, для арифметических операторов может показаться немного удивительным, что люди внезапно получают (byte)200 + (byte)100
, равным 44
, даже если это имеет смысл, когда вы тщательно рассматриваете используемые типы. С другой стороны, int
обычно считается типом, который «достаточно хорош» для арифметики для большинства типичных чисел, поэтому, продвигая оба аргумента до int
, вы получаете своеобразное поведение «просто работает» для большинства распространенных случаев.
Относительно того, почему эта логика была применена и к побитовым операторам - я полагаю, что это в основном для согласованности. Это приводит к одному простому правилу, которое является общим для всех небулевых двоичных типов.
Но все это в основном угадывает. Эрик Липперт, вероятно, должен был спросить о реальных мотивах этого решения для C# по крайней мере (хотя было бы немного скучно, если бы ответ был просто «как это делается на C/C++ и Java, и это достаточно хорошо так как мы не видели причин для его изменения »).
Этот вопрос отвечает на него более подробно: http://stackoverflow.com/questions/737781/left-bit-shifting-255-as-a-byte. У вас есть строковый литерал, который всегда передается в int. –