我刚刚发现C#不允许您对ulong
和int
执行按位操作。 int
,uint
,long
和ulong
的所有其他组合都可以使用,但是一个配对不会。
然而,如果不是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.
答案 0 :(得分:10)
此行为并非特定于按位操作。根据 C#语言规范,它适用于需要数字促销的所有二进制操作。
第7.6.3.2节描述了二进制数字促销。我强调了指明您所看到的行为的部分:
二进制数字促销包括按照它们在此处显示的顺序应用以下规则:
- 如果任一操作数的类型为
decimal
,则另一个操作数将转换为类型decimal
,否则如果另一个操作数的类型为float
或{{{}},则会发生绑定时错误1}}。- 否则,如果任一操作数的类型为
double
,则另一个操作数将转换为double
类型。- 否则,如果任一操作数的类型为
double
,则另一个操作数将转换为float
类型。- 否则,如果任一操作数的类型为
float
,则另一个操作数将转换为类型ulong
,否则如果另一个操作数的类型为{{1},则会发生绑定时错误}},ulong
,sbyte
或short
。- 否则,如果任一操作数的类型为
int
,则另一个操作数将转换为long
类型。- 否则,如果任一操作数的类型为
long
而另一个操作数的类型为long
,uint
或int,则两个操作数都将转换为类型sbyte
。- 否则,如果任一操作数的类型为
short
,则另一个操作数将转换为long
类型。- 否则,两个操作数都将转换为
uint
类型。
使用uint
时未发生问题的原因是允许编译器将int
表达式转换为其他类型,如第7.19节所述:
隐式常量表达式转换(第6.1.9节)允许将
const
类型的常量表达式转换为const int
,int
,sbyte
,{{1 }},byte
或short
,前提是常量表达式的值在目标类型的范围内。
由于ushort
的值(即uint
)适合ulong
,编译器会执行提升而不是触发错误。