C#数字常量

我有以下C#代码:

byte rule = 0; ... rule = rule | 0x80; 

产生错误:

无法将类型’int’隐式转换为’byte’。 存在显式转换(您是否错过了演员?)

[更新:问题的第一个版本错了……我误读了编译器输出]

添加强制转换不能解决问题:

 rule = rule | (byte) 0x80; 

我需要把它写成:

 rule |= 0x80; 

这看起来很怪异。 为什么|=运算符与|=任何不同 运营商?

有没有其他方法告诉编译器将常量视为一个字节?


@ Giovanni Galbo :是的,不是。 该代码处理外部设备中闪存的编程,逻辑上代表单个字节的存储器。 我可以稍后施展,但这似乎更明显。 我猜我的C传承太过分了!

@ Jonathon Holland :’as’语法看起来更整洁但不幸的是看起来不起作用……它产生:

as运算符必须与引用类型或可空类型一起使用(’byte’是不可为空的值类型)

 int rule = 0; rule |= 0x80; 

http://msdn.microsoft.com/en-us/library/kxszd0kx.aspx 为所有值类型定义运算符。 我认为这将产生预期的结果。 “| =”运算符是一个或那么赋值运算符,它只是rule = rule |的简写 0x80的。

关于C#的最重要的事情之一就是它可以让你根据它们的大小做滥用价值类型等疯狂的事情。 ‘int’与字节完全相同,但如果您尝试将它们同时用作两者,编译器将抛出警告。 简单地坚持使用一个(在这种情况下,int)效果很好。 如果您担心64位就绪,可以指定int32,但所有整数都是int32,即使在x64模式下运行。

C#没有字节的文字后缀。 u = uint,l = long,ul = ulong,f = float,m =十进制,但没有字节。 你必须施展它。

这有效:

 rule = (byte)(rule | 0x80); 

显然是表达’规则| 即使将0x80定义为’const byte 0x80’,0x80’也会返回一个int。

您正在寻找的术语是“Literal”,不幸的是C#没有字节文字。

这是所有C#文字的列表。

根据ECMA规范,第72页没有字节文字。 只有类型的整数文字:int,uint,long和ulong。

看起来你可能只需要以丑陋的方式去做: http : //msdn.microsoft.com/en-us/library/5bdb6693.aspx 。

差不多五年了,实际上没有人回答这个问题。

一些答案声称问题是缺少字节文字,但这是无关紧要的。 如果计算(byte1 | byte2)则结果为int类型。 即使“b”是字节的文字后缀, (23b | 32b)的类型仍然是int

接受的答案链接到声称该operator|的MSDN文章 是为所有整数类型定义的,但这也不是真的。

operator| 未在byte定义,因此编译器使用其通常的重载决策规则来选择在int上定义的版本。 因此,如果要将结果分配给一个byte ,则需要将其转换为:

 rule = (byte)(rule | 0x80); 

问题仍然存在,为什么rule |= 0x80; 工作?

因为C#规范有一个特殊的复合赋值规则,允许您省略显式转换。 在复合赋值x op= y ,规则是:

如果所选运算符是预定义运算符,如果所选运算符的返回类型可显式转换为x类型,并且如果y可隐式转换为x类型或运算符是移位运算符,则评估运算as x = (T)(x op y) ,其中T是x的类型,除了x只计算一次。

不幸的是,你唯一的办法就是按照自己的方式去做。 没有后缀将文字标记为字节。 | 运算符不提供隐式转换作为赋值(即初始化)。

显然是表达’规则| 即使将0x80定义为’const byte 0x80’,0x80’也会返回一个int。

我认为规则是像0x80这样的数字默认为int,除非你包含一个文字后缀。 所以对于表达式rule | 0x80 rule | 0x80 ,结果将是一个int,因为0x80是一个int,规则(这是一个字节)可以安全地转换为int。

根据C标准,字节总是在表达式中提升为int,甚至是常量。 但是,只要两个值都是UNSIGNED,高位就会被丢弃,因此操作应该返回正确的值。

同样,花车促进加倍,等等。

拉出K&R的副本。 一切都在那里。