为什么短基元有赋值运算符 (&=, +=) 但没有非赋值运算符 (&, +)
本文关键字:amp 赋值运算符 为什么 | 更新日期: 2023-09-27 18:13:03
我偶然发现了不允许对小于 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
...(定义的,因为这是处理器提供的(请参阅这个问题(,并且较短的类型被加宽并可以转换回 8 位或 16 位。但是,这在赋值运算符中起作用的原因是什么?首先,我假设在幕后,short
被强制转换为 int
,但随后你会有一个赋值/返回值short value = (some int)
,这应该会产生错误,因为强制转换不是隐式的。
换个说明:我在Visual Studio的即时窗口中尝试了一些代码,但在那里,更多的代码似乎有效。即时窗口可能会执行一些隐式强制转换,这通常是显式的。例如,允许在即时窗口中使用short a = (int)5;
。所以这无济于事。
真正的错误是由于在对它们进行操作时将较小的整数类型隐式转换为int
。
当您a & b
a
和 b
short
时,它们都将转换为 int 并且应用&
运算符,结果将为类型 int
,因此您无法返回方法声明中short
的int
。 一个简单的强制转换将解决问题。 (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
更小的类型上使用这些运算符(+=
、*=
、...(。
引擎盖下会发生什么??
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
但是,这在赋值运算符中起作用的原因是什么?
是的:因为否则赋值运算符永远无法用于这些类型 - 没有语法允许它工作。a += b
或a &= b
的期望是明确的,因此转换是自动执行的。
使用 a + b
或 a & b
,正如您已经注意到的:出于性能原因,这被扩大了; 语法的存在是为了将其放回原处,特别是(short)(a+b)
等。