C#或与强制转换问题

长不大的空想者 2019-05-17 10:42:13
我写了入下函数
byte value = 0;
value = value | (byte)(1 << i);
value |= (byte)(1 << i);


发现如下图错误



但是两条语句内容基本一样
我也用了转换
为啥第一个报错,而第二个不报错
...全文
141 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
需要将赋值号右边的表达式整体强制转换为byte类型
amouslion 2019-05-22
  • 打赏
  • 举报
回复
使用万能转换器试试,convert.To数据类型(转换变量名)
amouslion 2019-05-22
  • 打赏
  • 举报
回复
使用万能转换器试试,convert.To数据类型(转换变量名)
OrdinaryCoder 2019-05-17
  • 打赏
  • 举报
回复
按照1楼说的 value | (byte)(1 << i);这步的时候结果是一个int 需要强转成byte
游北亮 2019-05-17
  • 打赏
  • 举报
回复
2个byte类型进行运算符 | 操作的结果隐式提升为int, 而 |= 运算符的结果,维持运算符左边的类型了。
游北亮 2019-05-17
  • 打赏
  • 举报
回复
可以看到第2段代码多了1行转换: IL_0014: conv.u1 这个指令解释看官网: https://docs.microsoft.com/zh-cn/dotnet/api/system.reflection.emit.opcodes.conv_u1?redirectedfrom=MSDN&view=netframework-4.8
游北亮 2019-05-17
  • 打赏
  • 举报
回复
是的,我特意搜索了一下msdn,没找到相关的资料, 然后我写了2段代码:

int i = int.Parse("1");
byte value = 0;
var a = value | (byte)(1 << i);
对应生成的IL代码如下:
// [52 13 - 52 36]
IL_0000: ldstr        "1"
IL_0005: call         int32 [mscorlib]System.Int32::Parse(string)
IL_000a: stloc.0      // i

// [53 13 - 53 28]
IL_000b: ldc.i4.0

// [54 13 - 54 44]
IL_000c: ldc.i4.1
IL_000d: ldloc.0      // i
IL_000e: ldc.i4.s     31 // 0x1f
IL_0010: and
IL_0011: shl
IL_0012: conv.u1
IL_0013: or
另一段代码:
int i = int.Parse("1");
byte value = 0;
value |= (byte)(1 << i);
生成的IL代码:
// [60 13 - 60 36]
IL_0000: ldstr        "1"
IL_0005: call         int32 [mscorlib]System.Int32::Parse(string)
IL_000a: stloc.0      // i

// [61 13 - 61 28]
IL_000b: ldc.i4.0

// [62 13 - 62 37]
IL_000c: ldc.i4.1
IL_000d: ldloc.0      // i
IL_000e: ldc.i4.s     31 // 0x1f
IL_0010: and
IL_0011: shl
IL_0012: conv.u1
IL_0013: or
IL_0014: conv.u1
  • 打赏
  • 举报
回复
引用 1 楼 水边2 的回复:
2个byte类型进行运算符 | 操作的结果隐式提升为int,
而 |= 运算符的结果,维持运算符左边的类型了。
也就是说进行 | 操作时候,结果是int型的,而第二个|= 这种运算符相当于有个隐藏的强制转换?

110,566

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧