我有以下C#代码:
byte rule = 0;
...
rule = rule | 0x80;
产生错误:
无法将类型'int'隐式转换为'byte'。存在显式转换(您是否错过了演员?)
[更新:问题的第一个版本错了......我误读了编译器输出]
添加演员不解决问题:
rule = rule | (byte) 0x80;
我需要把它写成:
rule |= 0x80;
这看起来很奇怪。为什么|=
运算符与|
运算符有任何不同?
有没有其他方法告诉编译器将常量视为一个字节?
@ Giovanni Galbo :是的,不是。该代码处理外部设备中闪存的编程,逻辑上代表单个字节的存储器。我可以稍后施展,但这似乎更明显。我猜我的C传承太过分了!
@ Jonathon Holland :'as'语法看起来更整洁但不幸的是看起来不起作用......它产生了:
as运算符必须与引用类型或可空类型一起使用('byte'是不可为空的值类型)
答案 0 :(得分:34)
C#没有字节的文字后缀。 u = uint,l = long,ul = ulong,f = float,m =十进制,但没有字节。你必须施展它。
答案 1 :(得分:11)
这有效:
rule = (byte)(rule | 0x80);
显然是'规则|即使将0x80定义为'const byte 0x80',0x80'也会返回一个int。
答案 2 :(得分:9)
您正在寻找的术语是“Literal”,不幸的是C#没有字节字面值。
以下是all C# literals的列表。
答案 3 :(得分:6)
int rule = 0;
rule |= 0x80;
http://msdn.microsoft.com/en-us/library/kxszd0kx.aspx | operator是为所有值类型定义的。我认为这会产生预期的结果。 “| =”运算符是一个或那么赋值运算符,它只是rule = rule |的简写0x80的。
关于C#的最重要的事情之一就是它可以让你根据它们的大小做滥用价值类型等疯狂的事情。 'int'与字节完全相同,但如果您尝试将它们同时用作两者,编译器将抛出警告。简单地坚持使用一个(在这种情况下,int)效果很好。如果你担心64位准备就绪,你可以指定int32,但所有的int都是int32s,甚至在x64模式下运行。
答案 4 :(得分:3)
根据ECMA Specification, pg 72,没有字节文字。只有类型的整数文字:int,uint,long和ulong。
答案 5 :(得分:1)
看起来你可能只需要以丑陋的方式去做:http://msdn.microsoft.com/en-us/library/5bdb6693.aspx。
答案 6 :(得分:1)
差不多五年了,实际上没有人回答这个问题。
有几个答案声称问题是缺少字节文字,但这是无关紧要的。如果您计算(byte1 | byte2)
,则结果的类型为int
。即使“b”是字节的文字后缀,(23b | 32b)
的类型仍然是int
。
接受的答案链接到一篇MSDN文章声称为所有整数类型定义了operator|
,但事实并非如此。
operator|
上未定义 byte
,因此编译器使用其通常的重载解析规则来选择int
上定义的版本。因此,如果您想将结果分配给byte
,则需要将其转换为:
rule = (byte)(rule | 0x80);
问题仍然存在,为什么rule |= 0x80;
有效?
因为C#规范有一个特殊的复合赋值规则,允许您省略显式转换。在复合赋值x op= y
中,规则为:
如果所选运算符是预定义运算符,如果所选运算符的返回类型可明确转换为x类型,并且如果y可隐式转换为x类型或运算符是移位运算符,则操作被评估为
x = (T)(x op y)
,其中T是x的类型,除了x只被评估一次。
答案 7 :(得分:0)
不幸的是,你唯一的办法是按照你的方式去做。没有后缀将文字标记为字节。 |运算符不提供隐式转换作为赋值(即初始化)。
答案 8 :(得分:0)
显然是'规则| 即使你,0x80'也会返回一个int 将0x80定义为'const byte 0x80'。
我认为规则是像0x80这样的数字默认为int,除非你包含一个文字后缀。因此对于表达式rule | 0x80
,结果将是一个int,因为0x80是一个int,而规则(这是一个字节)可以安全地转换为int。
答案 9 :(得分:0)
根据C标准,字节总是在表达式中提升为int,甚至是常量。但是,只要两个值都是UNSIGNED,高位就会被丢弃,因此操作应该返回正确的值。
同样,花车也会增加一倍等等。
退出K& R的副本。它就在那里。