【问题标题】:return ulong in inline-if [duplicate]在 inline-if 中返回 ulong [重复]
【发布时间】:2015-09-30 16:48:17
【问题描述】:

我不能使用下面的代码有什么原因吗?

ulong test(int a, int b)
{
    return a == b ? 0 : 1;
}

它告诉我:

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

以下将起作用:

ulong test(int a, int b)
{
    return false ? 0 : 1;
}

我知道如何解决问题。我只是想知道原因。

谢谢。

【问题讨论】:

  • 在最后的代码块中,如果将false 替换为true 是否有效?也许有某种原因1 可以隐式转换为0 不能?
  • 已经测试过了,没什么区别。
  • false ? 0 : 1 是常量表达式。 return a == b ? 0 : 1 不是。 int 类型的常量表达式允许隐式转换为 ulong,如果它适合 ulong 范围。
  • 我认为的原因是编译器评估表达式,所以第二个没有错误。它将被编译为return 1
  • “我只是想知道原因。”因为这会无缘无故地增加编译器的复杂性。

标签: c# ternary-operator conditional-operator ulong


【解决方案1】:

我们来看看第二种方法得到的IL代码:

IL_0000:  nop
IL_0001:  ldc.i4.1
IL_0002:  conv.i8
IL_0003:  stloc.0
IL_0004:  br.s       IL_0006
IL_0006:  ldloc.0
IL_0007:  ret

IL_0001 处,文字1 被压入堆栈(因此表达式return false ? 0 : 1; 在编译时被评估并作为常量嵌入到IL 中)并且在IL_0002 处,该文字被转换为@ 987654326@。

来自 MSDN:

int 类型的常量表达式(第 7.15 节)可以转换为 类型 sbyte、byte、short、ushort、uint 或 ulong,提供的值为 常量表达式在目标类型的范围内。

由于1ulong数据类型的范围内,这样的转换总是会成功的。编译器知道这一点,因此会执行隐式转换。

【讨论】:

    【解决方案2】:

    类型为 int 的变量不能隐式转换为 ulong,因为 int 可以表示负值,而 ulong 不能。一个常量可以被隐式转换,前提是常量表达式的值是非负的。

    你的第二个例子是一个常量表达式。

    【讨论】:

      【解决方案3】:

      这将起作用:

      ulong test(int a, int b)
      {
          return a == b ? 0UL : 1UL;
      }
      

      你看,编译器从数字的大小推断类型,所以如果你想要一个特定的类型,你必须给出后缀。请参阅此 MSDN page 的文字部分

      编辑:正如向我指出的那样,这个问题并不是在寻找如何使其工作的答案。我相信链接的 MSDN 文章还是有一些价值的。它提供的信息可以解释为什么失败案例不起作用,但不能解释为什么其他案例通过。确实很有趣的问题。

      【讨论】:

      • 问题不在于如何使其发挥作用,而在于询问为什么第二种情况有效而第一种无效。
      • @juharr 原来如此。到了一天结束,我的大脑在这里炸了。尽管文字部分仍然适用,对吗?它解释了为什么它不起作用,但没有解释为什么第二种情况会起作用。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-05-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-08
      • 1970-01-01
      • 2018-09-24
      相关资源
      最近更新 更多