按位运算,ulong和int

时间:2016-12-14 15:22:16

标签: c# bitwise-operators

我刚刚发现C#不允许您对ulongint执行按位操作。 intuintlongulong的所有其他组合都可以使用,但是一个配对不会。

然而,如果不是int,我有一个const int,一切都很好。

这里发生了什么?为什么int & ulong无效,但const int & ulong有效?

断裂:

int mask = 0x1110;
ulong value = 0x1010;

var result = mask & value; // Compilation error: "Operator '&' cannot be applied to operands of type 'int' and 'ulong'"

工作:

const int mask = 0x1110;
ulong value = 0x1010;

var result = mask & value; // Works just fine.

1 个答案:

答案 0 :(得分:10)

此行为并非特定于按位操作。根据 C#语言规范,它适用于需要数字促销的所有二进制操作。

第7.6.3.2节描述了二进制数字促销。我强调了指明您所看到的行为的部分:

  

二进制数字促销包括按照它们在此处显示的顺序应用以下规则:

     
      
  • 如果任一操作数的类型为decimal,则另一个操作数将转换为类型decimal,否则如果另一个操作数的类型为float或{{{}},则会发生绑定时错误1}}。
  •   
  • 否则,如果任一操作数的类型为double,则另一个操作数将转换为double类型。
  •   
  • 否则,如果任一操作数的类型为double,则另一个操作数将转换为float类型。
  •   
  • 否则,如果任一操作数的类型为float,则另一个操作数将转换为类型ulong,否则如果另一个操作数的类型为{{1},则会发生绑定时错误}},ulongsbyteshort
  •   
  • 否则,如果任一操作数的类型为int,则另一个操作数将转换为long类型。
  •   
  • 否则,如果任一操作数的类型为long而另一个操作数的类型为longuint或int,则两个操作数都将转换为类型sbyte
  •   
  • 否则,如果任一操作数的类型为short,则另一个操作数将转换为long类型。
  •   
  • 否则,两个操作数都将转换为uint类型。
  •   

使用uint时未发生问题的原因是允许编译器将int表达式转换为其他类型,如第7.19节所述:

  

隐式常量表达式转换(第6.1.9节)允许将const类型的常量表达式转换为const intintsbyte,{{1 }},byteshort,前提是常量表达式的值在目标类型的范围内。

由于ushort的值(即uint)适合ulong,编译器会执行提升而不是触发错误。