【问题标题】:How to use C#'s ternary operator with two byte values?如何使用具有两个字节值的 C# 的三元运算符?
【发布时间】:2009-12-11 19:35:55
【问题描述】:

似乎没有办法像这样在两个字节上使用 C# 的三元运算符:

byte someByte = someBoolean ? 0 : 1;

该代码当前无法使用“无法将源类型 'int' 转换为目标类型 'byte'”进行编译,因为编译器将数字视为整数。显然没有指定后缀来表示 0 和 1 是字节,因此唯一的解决方法是 (a) 将结果转换为字节或 (b) 毕竟使用 if-else 控件。

有什么想法吗?

【问题讨论】:

  • 它对我来说编译得很好......你使用的是什么版本的框架?

标签: c# byte ternary


【解决方案1】:
byte someByte = someBoolean ? (byte)0 : (byte)1;

这里的强制转换不是问题,实际上IL代码根本不应该有强制转换。

编辑: 生成的 IL 如下所示:

L_0010: ldloc.0          // load the boolean variable to be checked on the stack
L_0011: brtrue.s L_0016  // branch if true to offset 16
L_0013: ldc.i4.1         // when false: load a constant 1
L_0014: br.s L_0017      // goto offset 17
L_0016: ldc.i4.0         // when true: load a constant 0
L_0017: stloc.1          // store the result in the byte variable

【讨论】:

  • 提问者已确认。他正在寻找替代品
  • @Randolpho:不,OP 说他可以转换 result - Lucero 的回答会转换 operands,这会产生不同的效果;强制转换是在编译时而不是执行时有效地完成的。
  • @Jon,谢谢。我刚刚尝试过,IL 没有显示强制转换(这是意料之中的,因为 IL 堆栈无论如何都只使用 32 位值,然后将其存储到一个字节中,从而有效地截断它)。
【解决方案2】:

你总是可以这样做的:

var myByte = Convert.ToByte(myBool);

这将产生 myByte == 0 为 false 和 myByte == 1 为 true。

【讨论】:

  • 我真的很惊讶有人花了这么长时间才提出建议。
【解决方案3】:
byte someByte = (byte)(someBoolean ? 0 : 1);

【讨论】:

    【解决方案4】:

    在 VS2008 上编译正常。

    更正:这在 VS2008 中编译正常:

    byte someByte = true ? 0 : 1;
    byte someByte = false ? 0 : 1;
    

    但是这个没有:

    bool someBool = true;
    byte someByte = someBool ? 0 : 1;
    

    奇怪!

    编辑:按照 Eric 的建议(见下面他的评论),我尝试了这个:

    const bool someBool = true;
    byte someByte = someBool ? 0 : 1;
    

    它编译完美。并不是说我不信任埃里克;为了完整起见,我只是想在此处包含此内容。

    【讨论】:

    • 是的,同样的旅程在这里......也许是你的第一个语句保证总是命中 0 的事实?
    • @tommieb75:确实崩溃了。
    • 很抱歉打破你的泡沫,但条件运算符的行为不是错误。首先参见第 7.18 节。由于所有操作数都是整数或布尔类型的编译时常量,因此在编译时计算条件运算符。它的计算结果是一个值为 1(或 0)的常量表达式,常量表达式的类型是 int。现在看第 6.1.8 节:“如果值在 byte 范围内,则可以将 int 类型的常量表达式转换为 byte”。所以你去;这是正确的,符合规范。
    • @Eric:因为我想你指的是我的评论......行为不同似乎仍然很奇怪。这是因为编译器也可以知道只有 0 或 1 将是运行时计算的结果,并且这两个常量都属于 6.1.8 节的规则。因此,如果代码在编译时工作的情况是正确的,那么编译器不接受 known 结果为 0 或 1 的运行时评估是否错误呢?跨度>
    • 当然,理论上这是可能的。但是请考虑一下您必须做些什么来编写具有该功能的编译器。假设你有 (A ? (B ? 0 : 1) : (C ? 2 : (D ? 5 : 265)))。编译器是否必须跟踪“此表达式的结果是 0、1、2、5 或 265,因此这不是可转换字节,而是 ubyte、ushort、short 或 int”?当然可以编写所有记账代码来跟踪条件表达式何时可能是几个常量之一,但我们有比该功能更高的优先级。
    猜你喜欢
    • 1970-01-01
    • 2020-10-06
    • 2016-07-02
    • 2021-08-01
    • 2021-04-03
    • 1970-01-01
    • 1970-01-01
    • 2019-07-21
    • 2023-03-05
    相关资源
    最近更新 更多