C#数值常数

C#数值常数,c#,casting,C#,Casting,我有以下C#代码: 这会产生错误: 无法将类型“int”隐式转换为“byte”。存在显式转换(是否缺少强制转换?) [更新:问题的第一个版本是错误的…我误读了编译器的输出] 添加强制转换无法解决问题: rule = rule | (byte) 0x80; 我需要这样写: rule |= 0x80; 这看起来很奇怪。为什么|=运算符与|运算符有任何不同 有没有其他方法告诉编译器将常量作为字节处理 @Giovanni Galbo:是和否。代码处理外部设备中闪存的编程,逻辑上表示单个字节的内存。

我有以下C#代码:

这会产生错误:

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

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

添加强制转换无法解决问题:

rule = rule | (byte) 0x80;
我需要这样写:

rule |= 0x80;
这看起来很奇怪。为什么
|=
运算符与
|
运算符有任何不同

有没有其他方法告诉编译器将常量作为字节处理


@Giovanni Galbo:是和否。代码处理外部设备中闪存的编程,逻辑上表示单个字节的内存。我可以稍后再投,但这似乎更明显。我想我的C语言遗产已经展示得太多了

@jonathonholland:“as”语法看起来更简洁,但不幸的是似乎不起作用。。。它产生:

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


看起来你可能不得不用丑陋的方式来做:。

C#没有字节的文字后缀。u=uint,l=long,ul=ulong,f=float,m=decimal,但没有字节。您必须强制转换它。

您要查找的术语是“文本”,不幸的是,C#没有字节文本


下面是一个列表。

根据没有字节文字。类型只有整数文本:int、uint、long和ulong。

不幸的是,您唯一的办法就是按照您现有的方式进行操作。没有后缀将文字标记为字节。|运算符不提供赋值(即初始化)所需的隐式转换。

此操作:

rule = (byte)(rule | 0x80);
显然,即使将0x80定义为“常量字节0x80”,表达式“rule | 0x80”也会返回一个int

int rule = 0;
rule |= 0x80;
|运算符是为所有值类型定义的。我认为这将产生预期的结果。“|=”运算符是一个or then assign运算符,它只是rule=rule | 0x80的简写

C#最有趣的一点是,它可以让你做一些疯狂的事情,比如仅仅根据大小滥用值类型。“int”与字节完全相同,只是如果您尝试同时使用它们,编译器将抛出警告。只需坚持使用一个(在本例中为int)就可以很好地工作。如果您关心64位就绪性,可以指定int32,但所有Int都是int32s,即使是在x64模式下运行

显然是“规则”的表达| 0x80'返回一个整数,即使您 将0x80定义为“常量字节0x80”

int rule = 0;
rule |= 0x80;

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

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

类似地,浮动会提升到双倍,等等


拿出《K&R》的副本。它都在里面。

差不多五年过去了,没有人真正回答这个问题

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

被接受的答案链接到一篇MSDN文章,声称
操作符|
是为所有整数类型定义的,但这也不是真的

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

rule = (byte)(rule | 0x80);
问题仍然存在,为什么
规则|=0x80工作

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

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


正如您所说,所有的int都是int32,语言(或CLR)规范不是保证了这一点吗?int是int32的C#别名,绝对不同于字节。JIT编译器是平台感知的,所以我们不需要。本机字长、寻址和针对各种本机原语的操作效率更可能涉及it如何在底层系统中分配托管数据(包括“原语”)。考虑到相同的代码可以编译为.Net Micro以及.NET CF(用于Xbox 360的电话和PowerPC的目标ARM)。这些系统甚至可以用不同的尾数来表示它们的数字,这对二进制运算有很大影响。用户:c语言规范中没有定义它。这里有一个例子:您可以声明和初始化一个字节变量,如下面的例子:byte myByte=255;在前面的声明中,整数文本255隐式地从int转换为byte。如果整数文字超过字节范围,则会发生编译错误。这是不正确的。即使您将0x80强制转换为一个字节,
|
运算符也会给您一个int。请尝试:
rule=rule |(byte)0x80以了解我的意思。但是,您可以将整个操作包装在括号中,并将其全部转换为byte:
rule=(byte)(