我很好奇为什么隐式强制转换失败...
int? someValue = SomeCondition ? ResultOfSomeCalc() : null;
以及为什么我必须执行显式转换
int? someValue = SomeCondition ? ResultofSomeCalc() : (int?)null;
在我看来,编译器拥有做出隐式转换决定所需的所有信息,不是吗?
我很好奇为什么隐式强制转换失败...
int? someValue = SomeCondition ? ResultOfSomeCalc() : null;
以及为什么我必须执行显式转换
int? someValue = SomeCondition ? ResultofSomeCalc() : (int?)null;
在我看来,编译器拥有做出隐式转换决定所需的所有信息,不是吗?
C# 3.0 规范的相关部分是 7.13,条件运算符:
?: 运算符的第二个和第三个操作数控制条件表达式的类型。设 X 和 Y 是第二个和第三个操作数的类型。然后,
如果 X 和 Y 是相同类型,则这是条件表达式的类型。否则,如果存在从 X 到 Y 的隐式转换(第 6.1 节),但不存在从 Y 到 X 的隐式转换,则 Y 是条件表达式的类型。否则,如果存在从 Y 到 X 的隐式转换(第 6.1 节),而不是从 X 到 Y,则 X 是条件表达式的类型。否则,无法确定表达式类型,并出现编译时错误。
我也很恼火它不能根据赋值推断类型,尤其是当它是一个值类型时。但是,当您进入对象层次结构时,这是有原因的。
如果“ResultOfSomeCalc()”返回一个“int?”,那么这将起作用。无论赋值左侧是什么,C# 都需要找出类型。所以你告诉它你将返回一个 null 或一个 int - 并且编译器中的逻辑不存在让它替换一个 Nullable 作为一个公分母。
请注意,这些变体确实有效,它可以帮助您理解:
object someValue = true ? new Nullable<int>(ResultOfSomeCalc()) : null;
object someValue = true ? (int?)ResultOfSomeCalc() : null;
希望这可以帮助。
看起来这似乎是编译器应该能够自己解决的问题,但是还有另一种方法可以做到这一点,使用 default 关键字。它可能比演员阵容更丑一点:
int? someValue = SomeCondition ? ResultofSomeCalc() : default(int?);
这种默认的使用似乎没有很好的文档记录,但确实有效。至少它使您不必在代码中乱扔魔术值(我认为 null/zero/false/etc. 确实是魔术值)。
另请参阅为什么此代码在 C# 中无效?
如果您的函数 ResultofSomeCalc() 返回 int?那么这将起作用。
如果您的函数返回 int,则编译器会发出警告:无法确定条件表达式的类型,因为 'int' 和 '' 之间没有隐式转换
我猜这就是您所看到的。条件运算符 "?:" 中的两个表达式必须具有相同的类型,或者必须通过隐式强制转换转换为相同的类型。
将 ResultOfSomeCalc 的返回类型更改为 int?,否则您需要对 null 表达式进行强制转换。
使您的函数 ResultOfSomeCalc() 的返回类型为 nullabel int,如 (int?)
int? someValue =(int?) SomeCondition ? ResultofSomeCalc() : (int?)null;