关于强制转换:C#数字常数

关于强制转换:C#数字常数

C# numeric constants

我有以下C#代码:

1
2
3
byte rule = 0;
...
rule = rule | 0x80;

产生错误:

Cannot implicitly convert type 'int' to 'byte'. An explicit conversion exists (are you missing a cast?)

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

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

1
rule = rule | (byte) 0x80;

我需要这样写:

1
rule |= 0x80;

看起来好像很奇怪。 为什么|=运算符与|运算符有什么不同?

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

// @ Giovanni Galbo:是和不是。 该代码用于处理外部设备中闪存的编程,并在逻辑上表示存储器的单个字节。 我可以稍后再投放,但这似乎更加明显。 我想我的C遗产显示得太多了!

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

The as operator must be used with a reference type or nullable type ('byte' is a non-nullable value type)


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


这有效:

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

显然,"规则|即使将0x80定义为"常量字节0x80"," 0x80"也将返回一个int。


您要查找的术语是"文字",不幸的是C#没有字节文字。

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


1
2
int rule = 0;
rule |= 0x80;

http://msdn.microsoft.com/zh-cn/library/kxszd0kx.aspx为所有值类型定义了运算符。我认为这将产生预期的结果。" | ="运算符是一个或然后分配的运算符,它只是rule = rule |的简写形式。 0x80的。

关于C#的最巧妙的事情之一是,它使您能够仅根据它们的大小来进行疯狂的事情,例如滥用值类型。" int"与一个字节完全相同,除了如果您尝试同时使用它们和两者,编译器将抛出警告。只需坚持使用一个(在本例中为int)即可。如果您担心64位就绪状态,可以指定int32,但所有int均为int32,即使以x64模式运行。


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


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

有几个答案声称问题出在缺少字节字面量,但这无关紧要。如果计算(byte1 | byte2),则结果为int类型。即使" b"是字节的字面后缀,(23b | 32b)的类型仍将是int

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

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

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

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

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

if the selected operator is a predefined operator, if the return type of the selected operator is explicitly convertible to the type of x, and if y is implicitly convertible to the type of x or the operator is a shift operator, then the operation is evaluated as x = (T)(x op y), where T is the type of x, except that x is evaluated only once.


看起来您可能只需要这样做就很丑陋:http://msdn.microsoft.com/en-us/library/5bdb6693.aspx。


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

同样,浮点数会增加一倍,依此类推

退出K&R副本。全部都在那里。


Apparently the expression 'rule |
0x80' returns an int even if you
define 0x80 as 'const byte 0x80'.

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


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


推荐阅读