C# 带补码运算符的编译器错误
我正在使用逻辑ANDC# 带补码运算符的编译器错误,c#,C#,我正在使用逻辑AND&=和补码~运算符,得到一个奇怪的编译器错误 // Constants private const byte XML_MATCH_ID = 0x01; private const byte XML_MATCH_MAC = 0x02; private const byte XML_MATCH_DEFAULT = (XML_MATCH_ID + XML_MATCH_MAC); // ... byte matchingTags = XML_MA
&=
和补码~
运算符,得到一个奇怪的编译器错误
// Constants
private const byte XML_MATCH_ID = 0x01;
private const byte XML_MATCH_MAC = 0x02;
private const byte XML_MATCH_DEFAULT = (XML_MATCH_ID + XML_MATCH_MAC);
// ...
byte matchingTags = XML_MATCH_DEFAULT;
// ... (reading XML nodes)
// Assume Machine ID doesn't match
matchingTags &= (byte)~XML_MATCH_ID; // Compiler error: Constant value '-2' cannot be converted to a 'byte'
// Assume MAC Address doesn't match
matchingTags &= (byte)~XML_MATCH_MAC; // Same compiler error but with "-3"
当我将上面的第一条语句更改为下面的等效语句时,一切都很好
matchingTags &= (0xff - XML_MATCH_ID);
为什么编译器会抛出此错误 编译器似乎试图将恭维词编译为常量。 我得到的编译器错误是“常量值计算溢出” 这并不奇怪<代码>字节是一个。(如果您正在查找,则应使用
sbyte
)
~XML\u MATCH\u ID
返回值为-2
的int
,该值不能强制转换为字节(uint8)
解决此问题的一种方法是将~XML\u MATCH\u ID
存储为临时int
变量,然后执行逻辑和:
int temp = ~XML_MATCH_ID; // temp now holds the value "-2"
byte temp2 = (byte)temp; // temp2 now holds the value "254"
matchingTags &= temp2;
或者完全避免使用补码运算符:
matchingTags &= (byte.MaxValue - XML_MATCH_ID);
如果是c#,则使用unchecked关键字:错误消息显示“使用unchecked语法覆盖”。为什么不使用未检查的语法覆盖错误?对我来说,这个编译器警告是意外的
XML\u MATCH\u ID
是一个无符号8位整数,因此使用补码运算符对其所有位进行逆变换将产生另一个无符号8位整数。你建议在这里避免使用补码运算符是明智的。@AlainD:不幸的是,你的逻辑似是而非。C#没有运算符结果类型与其操作数类型相同的规则。相反,C#使用重载解析从许多内置运算符中进行选择,并且没有内置的取一个字节的求反运算符。在这种情况下,C#编译器将选择一个接受int的编译器,因此结果是int。@bendik:虽然这个答案是正确的,因为它产生了正确的结果,但执行错误消息已经告诉用户的操作会更加习惯,用户神秘地没有做到这一点:使用未检查的语法覆盖错误报告。@EricLippert:我不知道,所以谢谢。有了这些信息,编译器错误就不那么神秘了!在我看来,Bendiks关于在这种情况下避免使用补码运算符(以及未选中的)的建议更容易阅读,因此是更合适的选择。