在C#中,为什么不能将条件运算符隐式地转换为可空类型

时间:2008-10-20 23:04:11

标签: c# conditional-operator nullable

我很好奇为什么隐式演员会失败...

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

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

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

在我看来,编译器具有进行隐式转换决策所需的所有信息,不是吗?

6 个答案:

答案 0 :(得分:27)

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

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

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

答案 1 :(得分:15)

我也很恼火它无法根据赋值推断出类型,特别是当它是一个值类型时。当你进入对象层次时,有一些原因。

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

请注意,这些变体可以使用,它可以帮助您理解:

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

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

希望这有帮助。

答案 2 :(得分:5)

看起来这似乎是编译器应该能够自己解决的问题,但还有另外一种方法可以使用default关键字。它可能是比演员更难看的一点:

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

这种默认使用似乎没有很好的记录,但确实有效。至少它可以让你不必使用魔法值来丢弃代码(我认为null / zero / false / etc确实是魔术值)。

答案 3 :(得分:4)

答案 4 :(得分:0)

如果你的函数ResultofSomeCalc()返回int?那就行了。

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

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

答案 5 :(得分:0)

使你的函数ResultOfSomeCalc()的返回类型为nullabel int like(int?)
诠释? someValue =(int?)SomeCondition? ResultofSomeCalc():( int?)null;