32

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

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

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

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

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

4

6 回答 6

29

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

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

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

于 2008-10-20T23:14:38.880 回答
15

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

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

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

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

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

希望这可以帮助。

于 2008-10-20T23:14:39.240 回答
5

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

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

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

于 2009-02-06T22:05:55.437 回答
4

另请参阅为什么此代码在 C# 中无效?

于 2008-10-20T23:28:13.177 回答
0

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

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

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

于 2008-10-20T23:30:45.603 回答
0

使您的函数 ResultOfSomeCalc() 的返回类型为 nullabel int,如 (int?)
int? someValue =(int?) SomeCondition ? ResultofSomeCalc() : (int?)null;

于 2015-04-14T10:13:17.140 回答