Why do C#'s binary operators always return int regardless of the format of their inputs?
如果我有两个
1 | byte c = a & b; |
生成有关将字节强制转换为int的编译器错误?即使我在
另外,我知道这个问题,但我不知道它在这里是如何应用的。这似乎是
Why do C#'s bitwise operators always return int regardless of the format of their inputs?
我总是不同意。本工程及
1 2 3 | long a = 0xffffffffffff; long b = 0xffffffffffff; long x = a & b; |
如果其中一个或两个参数是
Why do C#'s bitwise operators return int if their inputs are bytes?
这种行为是所有.NET编译器生成的中间语言IL设计的结果。虽然它支持短整型(byte、sbyte、short、ushort),但对它们的操作数量非常有限。只需加载、存储、转换、创建数组。这不是意外,这是一种可以在32位处理器上高效执行的操作,早在IL设计和RISC成为未来的时候。
二进制比较和分支操作仅在Int32、Int64、Native int、Native浮点、对象和托管引用上工作。这些操作数在任何当前CPU核心上都是32位或64位,确保JIT编译器能够生成高效的机器代码。
您可以在ECMA 335第I部分第12.1章和第III部分第1.5章中了解更多有关它的信息。
我在这里写了一篇更广泛的文章。
没有为字节类型(以及其他类型)定义二进制运算符。事实上,所有二进制(数字)运算符仅对以下本机类型起作用:
- int
- 无符号整型
- 长的
- 无符号长整型
- 浮动
- 双重的
- 十进制的
如果涉及任何其他类型,它将使用上述类型之一。
所有这些都在C规范版本5.0(第7.3.6.2节)中:
对预定义的+、–、*、/、%、&;、、^、=、!=、>、<、>=和<=二进制运算符。二进制数字提升将两个操作数隐式转换为一个公共类型,对于非关系运算符,该类型也将成为操作的结果类型。二进制数字提升包括按以下规则在此处出现的顺序应用它们:
- 如果其中一个操作数是decimal类型,则另一个操作数将转换为decimal类型,如果另一个操作数是float或double类型,则会发生编译时错误。
- 否则,如果其中一个操作数是double类型,则另一个操作数将转换为double类型。
- 否则,如果其中一个操作数是float类型,则另一个操作数将转换为float类型。
- 否则,如果其中一个操作数是ulong类型,则另一个操作数将转换为ulong类型,如果另一个操作数是sbyte、short、int或long类型,则会出现编译时错误。
- 否则,如果其中一个操作数是long类型,则另一个操作数将转换为long类型。
- 否则,如果其中一个操作数是uint类型,而另一个操作数是sbyte、short或int类型,则两个操作数都将转换为long类型。
- 否则,如果其中一个操作数是uint类型,则另一个操作数将转换为uint类型。
- 否则,两个操作数都将转换为int类型。
这是因为&;是在整数上定义的,而不是在字节上定义的,编译器将您的两个参数隐式地强制转换为int。