看看这段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数组)更快(因为缓存命中)。但是大量的字节强制转换散布在代码中,使得代码更加难以阅读。


当前回答

从.NET框架代码:

// bytes
private static object AddByte(byte Left, byte Right)
{
    short num = (short) (Left + Right);
    if (num > 0xff)
    {
        return num;
    }
    return (byte) num;
}

// shorts (int16)
private static object AddInt16(short Left, short Right)
{
    int num = Left + Right;
    if ((num <= 0x7fff) && (num >= -32768))
    {
        return (short) num;
    }
    return num;
}

使用。net 3.5及以上版本进行简化:

public static class Extensions 
{
    public static byte Add(this byte a, byte b)
    {
        return (byte)(a + b);
    }
}

现在你可以做:

byte a = 1, b = 2, c;
c = a.Add(b);

其他回答

我想我以前在什么地方见过这个。从这篇文章,旧的新事物:

假设我们生活在一个幻想的世界 对'byte'的操作导致了什么 “字节”。

byte b = 32;
byte c = 240;
int i = b + c; // what is i?

在这个幻想世界里,i的值 应该是16岁!为什么?因为这两个 +操作符的操作数都是 字节,因此“b+c”的和计算为 一个字节,由于 整数溢出。(而且,正如我所指出的 之前,整数溢出是新的 安全攻击向量。)

编辑:Raymond实质上是在捍卫C和c++最初采用的方法。在评论中,他从语言向后兼容的角度为c#采用了相同的方法进行了辩护。

从.NET框架代码:

// bytes
private static object AddByte(byte Left, byte Right)
{
    short num = (short) (Left + Right);
    if (num > 0xff)
    {
        return num;
    }
    return (byte) num;
}

// shorts (int16)
private static object AddInt16(short Left, short Right)
{
    int num = Left + Right;
    if ((num <= 0x7fff) && (num >= -32768))
    {
        return (short) num;
    }
    return num;
}

使用。net 3.5及以上版本进行简化:

public static class Extensions 
{
    public static byte Add(this byte a, byte b)
    {
        return (byte)(a + b);
    }
}

现在你可以做:

byte a = 1, b = 2, c;
c = a.Add(b);

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

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

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

例如,要执行Int16算术:

short a = 2, b = 3;

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

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

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

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

我怀疑c#实际上是在调用int上定义的运算符+(它返回一个int,除非你在一个检查块中),并隐式地将你的bytes/shorts都转换为int。这就是为什么行为看起来不一致。