看看这段c#代码:

byte x = 1;
byte y = 2;
byte z = x + y; // ERROR: Cannot implicitly convert type 'int' to 'byte'

在字节(或短)类型上执行的任何数学运算的结果都隐式地转换回整数。解决方案是显式地将结果转换回一个字节:

byte z = (byte)(x + y); // this works

我想知道的是为什么?是建筑吗?哲学吗?

我们有:

Int + Int = Int 长+长=长 浮+浮=浮 Double + Double = Double

所以为什么不呢:

字节+字节=字节 空头+空头=空头?

一点背景知识:我正在对“小数字”(即< 8)执行一个长列表的计算,并将中间结果存储在一个大数组中。使用字节数组(而不是int数组)更快(因为缓存命中)。但是大量的字节强制转换散布在代码中,使得代码更加难以阅读。


当前回答

我记得曾经读过Jon Skeet(现在找不到了,我会继续找)关于字节如何实际上不会重载+操作符的内容。事实上,当像您的示例中那样添加两个字节时,每个字节实际上都被隐式转换为int。其结果显然是一个整型。至于为什么要这样设计,我将等待乔恩·斯基特自己发布:)

编辑:找到了!这里有关于这个话题的很棒的信息。

其他回答

这是我对这个话题的大部分回答,首先是针对这里的一个类似问题。

默认情况下,所有小于Int32的整数运算在计算前四舍五入到32位。结果为Int32的原因仅仅是让它在计算后保持原样。如果检查MSIL算术操作码,它们操作的唯一整型数字类型是Int32和Int64。这是“故意的”。

如果您希望结果以Int16格式返回,则在代码中执行强制转换或编译器(假设)在“底层”发出转换都无关紧要。

例如,要执行Int16算术:

short a = 2, b = 3;

short c = (short) (a + b);

这两个数字将扩展为32位,然后相加,然后截短为16位,这是MS所希望的。

使用短(或字节)的优势主要是在有大量数据(图形数据、流等)的情况下存储。

除了所有其他伟大的评论,我想我要添加一个小花絮。很多评论都想知道为什么int、long和几乎任何其他数字类型都不遵循这个规则…返回一个“更大”的类型以响应算术。

A lot of answers have had to do with performance (well, 32bits is faster than 8bits). In reality, an 8bit number is still a 32bit number to a 32bit CPU....even if you add two bytes, the chunk of data the cpu operates on is going to be 32bits regardless...so adding ints is not going to be any "faster" than adding two bytes...its all the same to the cpu. NOW, adding two ints WILL be faster than adding two longs on a 32bit processor, because adding two longs requires more microops since you're working with numbers wider than the processors word.

I think the fundamental reason for causing byte arithmetic to result in ints is pretty clear and straight forward: 8bits just doesn't go very far! :D With 8 bits, you have an unsigned range of 0-255. That's not a whole lot of room to work with...the likelyhood that you are going to run into a bytes limitations is VERY high when using them in arithmetic. However, the chance that you're going to run out of bits when working with ints, or longs, or doubles, etc. is significantly lower...low enough that we very rarely encounter the need for more.

从字节到int的自动转换是合乎逻辑的,因为字节的规模是如此之小。从整型到长型,从浮点数到双精度浮点数等自动转换是不符合逻辑的,因为这些数字具有显著的比例。

我记得曾经读过Jon Skeet(现在找不到了,我会继续找)关于字节如何实际上不会重载+操作符的内容。事实上,当像您的示例中那样添加两个字节时,每个字节实际上都被隐式转换为int。其结果显然是一个整型。至于为什么要这样设计,我将等待乔恩·斯基特自己发布:)

编辑:找到了!这里有关于这个话题的很棒的信息。

没有为字节定义加法。所以它们被转换为int类型进行加法运算。对于大多数数学运算和字节来说都是如此。(请注意,这是在旧语言中使用的方式,我假设它在今天仍然适用)。

根据c#语言规范1.6.7.5 7.2.6.2二进制数值提升,如果不能将操作数归入其他类别,则将两个操作数都转换为int。我的猜测是,他们没有重载+操作符以将字节作为参数,但希望它的行为有点正常,所以他们只是使用int数据类型。

c#语言规范