Почему операции сдвига всегда приводят к подписанному int, когда операнд <32 бит

Почему операции сдвига в unsigned ints дают результат без знака, но операции с меньшими неподписанными операндами приводят к подписанному int?

int signedInt = 1;
int shiftedSignedInt = signedInt << 2;

uint unsignedInt = 1;
uint shiftedUnsignedInt = unsignedInt << 2;     //OK. unsigned result

short signedShort = 1;
int shiftedsignedShort = signedShort << 2;

ushort unsignedShort = 1;
uint shiftedUnsignedShort = unsignedShort << 2; //CS0266: Can't cast int to uint

sbyte signedByte = 1;
int shiftedSignedByte = signedByte << 2;

byte unsignedByte = 1;
uint shiftedUnsignedByte = unsignedByte << 2;   //CS0266: Can't cast int to uint

Ответ 1

Операторы сдвига предопределены только для этих случаев (сдвиг влево):

int operator <<(int x, int count);  (1)
uint operator <<(uint x, int count); (2)
long operator <<(long x, int count);  (3)
ulong operator <<(ulong x, int count); (4)

Выражение uint shiftedUnsignedShort = unsignedShort << 2 интерпретируется как (1) -ый случай (неявный отбрасывание от ushort до int и (int)2), поэтому он выполнял предупреждение о незаконном литье (нет никакого скрытого отбрасывания из результата int для ushort).
Такую же ситуацию мы можем видеть для uint shiftedUnsignedByte = unsignedByte << 2. Он также интерпретируется как (1) -ый случай (неявное переброс из байта в int и (int)2, но не подразумеваемый листинг результирующего значения для uint).

Вы можете решить эти проблемы, используя следующий подход:

uint shiftedUnsignedShort = (uint)unsignedShort << 2  //force use the (2)-nd shift operator case  
uint shiftedUnsignedByte = (uint)unsignedByte << 2;   //force use the (2)-nd shift operator case

Ответ 2

В Операторы сдвига В статье MSDN упоминается, что предопределенные операторы сдвига существуют только для типов int, uint, long, ulong. Для всех остальных типов они перегружены. Для всех операций сдвига второй операнд должен всегда иметь тип int. Поэтому любой короткий тип всегда отливается в int перед выполнением операции переключения.

Ответ 3

В соответствии с Wikipedia << и >> представляют два разных оператора. Логический сдвиг vor ulong и uint и арифметический сдвиг для int и long.

Теперь моя догадка (!) заключается в том, что "undefined" ushort или ubyte получают бросок в int а не uint.

Извините, но все, что я могу предложить.