我偶然发现在小于32位的基本类型上不允许按位或算术运算的行为,但事实上允许相应的赋值操作:
short BitwiseAnd(short a, short b) { return a & b; } // error
short BitwiseAndAssignment(ref short a, short b) { a &= b; } // works
short Add(short a, short b) { return a + b; } // error
short AddAssignment(ref short a, short b) { a += b; } // works
对于byte
,sbyte
和ushort
等其他短基本类型,同样的行为也适用。
我理解算术和逻辑运算是针对32位及更大类型(int
,long
...)定义的,因为它是处理器提供的(see this question),并且较短的类型加宽,可以返回8或16位。但是,为什么这可以在赋值运算符中起作用?首先我假设在幕后,short
被转换为int
,但是你会有一个赋值/返回值short value = (some int)
,这会产生错误,因为强制转换不是隐式的。
另一个注意事项:我在Visual Studio的即时窗口中尝试了一些代码,但在那里,还有更多的代码可以工作。即时窗口可能会执行一些隐式转换,这通常是明确的。例如,在即时窗口中允许short a = (int)5;
。所以这没有帮助。
答案 0 :(得分:2)
真正的错误是由于在对它们进行操作时将较小的整数类型隐式转换为int
。
当a & b
a
和b
为short
时,它们都会转换为int并且&
运算符适用,结果将会属于int
类型,因此您无法在方法声明中将int
作为short
返回。一个简单的演员将解决问题。 (short)(a & b)
。
short BitwiseAnd(short a, short b) { return (short)(a & b); } //no error!
当你有
时short BitwiseAndAssignment(ref short a, short b) { a &= b; }
编译器会为你生成强制转换,否则你不能在比+=
更小的类型上使用这些类型的运算符(*=
,int
,...)。< / p>
幕后会发生什么?
short a = 1;
short b = 2;
short c = a + b; //error!
为什么呢?因为+运算符没有重载来接收两个short
参数。由于short
和int
之间存在隐式转换,因此方法解析将选择具有两个int作为输入参数的重载。因此它会将a
和b
投射到int
,然后调用所选的重载,返回int
。因为它返回int
,所以您无法将其存储在short
变量中,因此您需要明确地将其强制转换。
short c = (short)(a + b)//this will work
答案 1 :(得分:1)
但是,有什么理由可以在赋值运算符中使用它?
是的:因为否则赋值运算符永远不能用于这些类型 - 没有语法允许它工作。 a += b
或a &= b
的期望是明确的,因此转化会自动执行。
对于a + b
或a & b
,正如您已经注意到的那样:出于性能原因,这已经扩大了;存在语法以将其放回去,特别是(short)(a+b)
等。