19

我有以下 C# 代码:

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

这会产生错误:

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

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

添加演员表不能解决问题:

rule = rule | (byte) 0x80;

我需要把它写成:

rule |= 0x80;

这看起来很奇怪。为什么|=运营商与运营商有任何不同|

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


//@Giovanni Galbo:是的,不是的。该代码处理外部设备中闪存的编程,并在逻辑上表示单个字节的内存。我可以稍后再施放它,但这似乎更明显。我猜我的 C 血统暴露得太多了!

@ Jonathon Holland:'as' 语法看起来更整洁,但不幸的是似乎不起作用......它产生:

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

4

10 回答 10

34

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

于 2008-09-04T02:03:09.063 回答
11

这有效:

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

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

于 2008-09-04T02:05:53.440 回答
9

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

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

于 2008-09-04T02:04:33.787 回答
6
int rule = 0;
rule |= 0x80;

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

关于 C# 的一个更漂亮的事情是它可以让你做一些疯狂的事情,比如仅仅根据它们的大小来滥用值类型。'int' 与字节完全相同,但如果您尝试同时使用它们,编译器会抛出警告。简单地坚持一个(在这种情况下,int)效果很好。如果您担心 64 位就绪,您可以指定 int32,但所有 int 都是 int32s,即使在 x64 模式下运行。

于 2008-09-04T02:10:47.860 回答
3

根据ECMA 规范,第 72 页没有字节文字。仅适用于以下类型的整数文字:int、uint、long 和 ulong。

于 2008-09-04T02:05:05.393 回答
2

将近五年过去了,没有人真正回答过这个问题。

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

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

operator|未定义 onbyte因此编译器使用其通常的重载解析规则来选择定义 on 的版本int。因此,如果要将结果分配给 a ,则byte需要对其进行强制转换:

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

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

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

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

于 2013-06-02T16:35:37.257 回答
1

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

于 2008-09-04T02:01:45.370 回答
0

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

于 2008-09-04T02:05:30.587 回答
0

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

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

于 2008-09-04T02:26:33.423 回答
0

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

同样,浮点数提升为双精度等。

拉出 K&R 的副本。都在里面。

于 2013-01-28T02:24:00.310 回答