【问题标题】:In C# why can't a conditional operator implicitly cast to a nullable type在 C# 中,为什么条件运算符不能隐式转换为可空类型
【发布时间】:2010-09-18 05:28:03
【问题描述】:

我很好奇为什么隐式转换失败...

int? someValue = SomeCondition ? ResultOfSomeCalc() : null;

以及为什么我必须执行显式转换

int? someValue = SomeCondition ? ResultofSomeCalc() : (int?)null;

在我看来,编译器拥有做出隐式转换决定所需的所有信息,不是吗?

【问题讨论】:

  • 我不会自己编辑您的标题,但我建议您将单词 terrnary 更改为条件 - 运算符称为条件运算符。它是 a 三元运算符 - 目前是唯一一个 - 但除了操作数的数量之外,它没有描述任何其他内容。
  • 也许我比较厚脸皮,但我会...
  • @MarcGravell 我很厚脸皮,希望是正确的——那么标题不应该是**the** conditional operator 吗? :)
  • @PhilippM 我认为在上下文中很明显它的意思是“一个实例”,所以(收缩那个)“a”感觉很好

标签: c# conditional-operator nullable


【解决方案1】:

C# 3.0规范的相关部分是7.13,条件运算符:

?: 运算符的第二个和第三个操作数控制条件表达式的类型。设 X 和 Y 是第二个和第三个操作数的类型。那么,

如果 X 和 Y 是同一类型,那么这是条件的类型 否则,如果存在从 X 到 Y 的隐式转换(第 6.1 节),而不是从 Y 到 X,则 Y 是条件表达式的类型。 否则,如果存在从 Y 到 X 的隐式转换(第 6.1 节),而不是从 X 到 Y,则 X 是条件表达式的类型。 否则,无法确定表达式类型,并出现编译时错误。

【讨论】:

  • 总而言之,它没有考虑您在操作结果中分配的类型。它只是试图找出等式类型的右侧 - 忽略 Nullable 类型。
  • 但是让我们考虑三元链的情况。它怎么会知道?
  • @DJ Floetic:它会从 'innermost' ?: 运算符开始,找出结果的类型,然后解决问题。
  • 如果每个都可以隐式转换成另一个呢?
【解决方案2】:

我也很恼火它不能根据赋值推断类型,尤其是当它是一个值类型时。但是,当您进入对象层次结构时,这是有原因的。

如果“ResultOfSomeCalc()”返回一个“int?”,那么这将起作用。无论赋值左侧是什么,C# 都需要找出类型。所以你告诉它你将返回一个 null 或一个 int - 并且编译器中的逻辑不存在让它替换一个 Nullable 作为一个公分母。

请注意,这些变体确实有效,它可以帮助您理解:

object someValue = true ? new Nullable<int>(ResultOfSomeCalc()) : null;

object someValue = true ? (int?)ResultOfSomeCalc() : null;

希望这会有所帮助。

【讨论】:

    【解决方案3】:

    这似乎是编译器应该能够自行解决的问题,但还有另一种方法可以做到这一点,即使用 default 关键字。它可能比演员阵容更丑一点:

    int? someValue = SomeCondition ? ResultofSomeCalc() : default(int?);
    

    这种对默认值的使用似乎没有很好的文档记录,但确实有效。至少它使您不必在代码中乱扔魔术值(我认为 null/zero/false/etc. 确实是魔术值)。

    【讨论】:

      【解决方案4】:

      【讨论】:

      • 哇,多么糟糕的措辞问题。我永远不会发现。
      【解决方案5】:

      如果你的函数 ResultofSomeCalc() 返回 int?那么这将起作用。

      如果您的函数返回 int,则编译器会发出警告: 无法确定条件表达式的类型,因为 'int' 和 '' 之间没有隐式转换
      我猜这就是你所看到的。条件运算符“?:”中的两个表达式必须具有相同的类型,或者必须通过隐式强制转换转换为相同的类型。

      将 ResultOfSomeCalc 的返回类型更改为 int?,否则您需要对 null 表达式进行强制转换。

      【讨论】:

        【解决方案6】:

        将函数 ResultOfSomeCalc() 的返回类型设置为 nullabel int,例如 (int?)
        诠释? someValue =(int?) SomeCondition ? ResultofSomeCalc() : (int?)null;

        【讨论】:

          猜你喜欢
          • 2016-06-01
          • 2011-01-14
          • 2013-09-17
          • 1970-01-01
          • 1970-01-01
          • 2016-03-07
          • 1970-01-01
          • 2012-09-14
          • 2022-01-22
          相关资源
          最近更新 更多