【问题标题】:Conditional Operator Return Type with literal digits带有文字数字的条件运算符返回类型
【发布时间】:2013-09-01 02:09:48
【问题描述】:

?: Operator (C# Reference)

first_expression 和 second_expression 的类型必须是 相同,或者必须存在从一种类型到另一种类型的隐式转换。

Integer literals

如果字面量没有后缀,则它具有这些类型中的第一个 它的值可以表示为:int、uint、long、ulong。

考虑:

var value = test ? (Int64)1 : 0;

0,没有后缀的十进制数字文字将被转换为intint 可以隐式转换为 Int64。由于这种转换只发生在一个方向上,我们可以放心地返回值将是 Int64。

但是:

var value = test ? (UInt64)1 : 0;

UInt64int 不能隐式相互转换,但是这段代码编译运行,结果类型为UInt64

0 的类型在什么时候确定?

如果这两种类型可以相互隐式转换,那么你最终会得到这两种类型中的哪一种? (我认为这不会正常发生,但用户生成的类可以实现这种转换。)

先前的研究:
我发现了其他几个标题相似的问题,但它们都与 null 或可为 null 的类型有关。

相关性: 这在我的代码中很重要,因为我们会立即将此结果传递给 ByteWriter.Write,并希望最终得到正确的重载,从而写入正确的字节数。这些例子当然被大大简化了。

替代语法使结果显式可能是清晰的最佳选择,无论在没有显式转换的情况下实际发生了什么:

var value = test ? (UInt64)1 : (UInt64)0;

【问题讨论】:

    标签: c# implicit-conversion conditional-operator return-type


    【解决方案1】:

    没错,通用 int 不能隐式转换为 UInt 任何长度。但在这里我们不是在谈论通用的、未知的int。我们正在谈论0,它可以转换(甚至在编译时,我怀疑编译器正在这样做)转换为UInt

    我建议您使用 int 参数(或编译器无法通过数据流分析推断的另一个值),看看会发生什么。

    【讨论】:

    • 在值是否为常量之前我遇到了一些问题,我怀疑这与此处相关,但严格按照引用的文档,这应该不起作用。
    • @DeniseSkidmore 这很重要,不管它是否恒定。要引用的文档是 Implicit constant expression conversions。请注意,在第一个项目符号中,int can 隐式转换为 ulong(使用常量)。
    【解决方案2】:

    请注意,当数字是编译时常量(文字)时,整数类型之间存在一组隐式转换,而当它们不是常量时,则存在另一组转换。

    你有趣的例子是:

    var value = test ? (UInt64)1 : 0;
    

    也可以写成:

    var value = test ? 1ul : 0;
    

    其中ul 后缀表示ulong,即System.UInt64

    当使用文字(常量)时,确实存在从 int (System.Int32) 到 ulong 的隐式转换,但仅当 int 常量为非负数时。真的是一样的:

    const ulong a = 1ul;
    const int b = 0;
    var value = test ? a : b;  // also works fine
    

    正如我所说,它可以工作,因为从 int(因为编译器知道 b 不是负数)到 ulong 的隐式常量转换。

    现在,把const拿走即可:

    ulong a = 1ul;
    int b = 0;
    var value = test ? a : b;  // compile-time error, no implicit conversion in either direction!
    

    我们看到,对于非常数,不存在任一方向的隐式转换,因此对于 ab 没有最佳通用类型,这将失败。

    【讨论】:

      猜你喜欢
      • 2012-01-22
      • 2011-07-20
      • 2019-07-09
      • 2021-10-22
      • 2019-09-09
      • 1970-01-01
      • 2021-09-17
      相关资源
      最近更新 更多