我有以下 C# 代码:

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

这会产生错误:

无法将类型“int”隐式转换为“byte”。存在显式转换(您是否缺少强制转换?)

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

添加演员阵容 解决问题:

rule = rule | (byte) 0x80;

我需要将其写为:

rule |= 0x80;

这看起来很奇怪。为什么是 |= 运算符与任何不同 | 操作员?

还有其他方法告诉编译器将常量视为字节吗?


@乔瓦尼·加尔博 :是和否。该代码处理外部设备中闪存的编程,并在逻辑上表示存储器的单个字节。我可以稍后再施放,但这似乎更明显。我猜我的 C 血统表现得太多了!

@乔纳森·霍兰德 :“as”语法看起来更简洁,但不幸的是似乎不起作用......它产生:

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

有帮助吗?

解决方案

int rule = 0;
rule |= 0x80;

http://msdn.microsoft.com/en-us/library/kxszd0kx.aspx |为所有值类型定义了操作员。我认为这会产生预期的结果。“ | =”操作员是一个或分配运算符,这仅是规则=规则|的速记。 0x80。

C# 的妙处之一是它可以让你做一些疯狂的事情,比如仅仅根据值类型的大小来滥用它们。“int”与字节完全相同,只是如果您尝试同时使用它们,编译器会抛出警告。简单地坚持使用一个(在本例中为 int)效果很好。如果您担心 64 位准备情况,可以指定 int32,但所有 int 都是 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”是 byte 类型的文字后缀 (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 仅计算一次。

不幸的是,你唯一的办法就是按照你现有的方式去做。没有后缀将文字标记为字节。|操作员不提供隐式转换作为作业(即初始化)会。

显然是“规则” |即使您将0x80定义为“ const byte 0x80”,0x80'也会返回int。

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

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

同样,浮动会提升为双倍,等等。

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top