代码之家  ›  专栏  ›  技术社区  ›  Tim Jarvis

在C#中,为什么条件运算符不能隐式转换为可以为null的类型

  •  32
  • Tim Jarvis  · 技术社区  · 16 年前

    我很好奇为什么隐式演员在。。。

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

    以及为什么我必须表演露骨的演员阵容

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

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

    6 回复  |  直到 15 年前
        1
  •  29
  •   Brian Liang    16 年前

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

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

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

        2
  •  15
  •   TheSoftwareJedi jac    16 年前

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

    如果“ResultOfSomeCalc()”返回“int?”,那么这将起作用 .C#需要找出类型,而不管赋值的左边是什么。因此,你告诉它你将返回null或int,而编译器中的逻辑不存在,无法让它替换Nullable作为公分母。

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

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

    希望这能有所帮助。

        3
  •  5
  •   Mr. Putty    16 年前

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

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

    这种默认值的使用似乎没有很好的记录,但确实有效。至少它可以让你不必在代码中添加魔法值(我认为空/零/假等确实是魔法值)。

        4
  •  4
  •   Community CDub    8 年前
        5
  •  0
  •       16 年前

    如果你的函数ResultofSomeCalc()返回int?那么这将奏效。

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

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

        6
  •  0
  •   Abdus Salam Azad    10 年前

    将函数ResultOfSomeCalc()的返回类型设置为null标签int,类似于(int?)
    int?someValue=(int?)SomeCondition?SomeCalc()的结果:(int?)null;