条件运算符和if-else之间的差异:

时间:2014-01-10 10:26:42

标签: c# conditional-operator

我看了this question,发现Tim Schmelter's answer

  

顺便说一句,这是条件运算符和if-else

之间的差异之一

你可以查看这个问题的答案,我找不到原因吗?

如果条件运算符像if-else那样工作,为什么if else不需要强制转换

问题:

int? l = lc.HasValue ? (int)lc.Value : null; 

“Tim Schmelter”回答:

您还必须投射null

int? l = lc.HasValue ? (int)lc.Value : (int?)null; 

顺便说一句,这是conditional operatorif-else之间的差异之一:

if (lc.HasValue)
    l = (int)lc.Value;
else
    l = null;  // works

3 个答案:

答案 0 :(得分:5)

单独的文字null没有类型,但它可以隐式转换为任何引用类型和任何Nullable<>类型。在表达式中:

x = null

其中x被赋值为null,编译器可以很容易地从变量的类型(或字段或属性或参数或其他)x推断null字面值应该是什么转换成。例如,如果x属于string类型,则null应代表null引用,而如果x属于int?类型,则null代表Nullable<int> HasValue为假的实例。

如果x的类型为int,则不存在隐式转换,并且上述表达式不会编译。

(声明var x = null;var不合法,因为null本身没有类型。)

另一方面,在表达式中:

someBoolean ? 42 : null /* illegal */

编译器无法确定将null转换为什么类型。请注意,int既不是引用类型,也不是Nullable<>类型。

如果您将包装表示为可空,请使用:

someBoolean ? (int?)42 : null

或:

someBoolean ? 42 : (int?)null

在这两种情况下,编译器都会自动看到另一个操作数(在冒号:的另一侧)也必须隐式转换为int?

如果您将装箱指代int的某个基类或接口,请写下:

someBoolean ? (object)42 : null

或:

someBoolean ? 42 : (object)null

现在,上面的表达式可能是包含更大表达式的子表达式,但编译器仍然需要?:表达式的类型才能自行清除。例如:

int? x;
x = someBoolean ? 42 : null; // still illegal!

即使子表达式someBoolean ? 42 : null出现在较大的表达式x = someBoolean ? 42 : null中,其中x确实具有类型,但子表达式仍必须“内在地”获取其类型。 x的类型不能“泄漏”子表达式。对于许多新的C#开发人员来说,这种“语法”似乎是一个惊喜。像你这样的问题经常出现,例如, Nullable type issue with ?: Conditional Operator以及与之关联的主题。

答案 1 :(得分:1)

if语句不会产生值,因此“then”和“else”部分中的语句不需要以任何方式兼容。

条件运算符产生一个值,因此两个部分必须以某种方式兼容,以便编译器确定表达式的类型。

答案 2 :(得分:0)

MSDN对条件运算符说:

* first_expression和second_expression的类型必须相同,或者从一种类型到另一种类型必须存在隐式转换。*

这就是原因。在 if-else 构造函数中, else 块中的代码独立于 if 块中的代码,因此类型转换可以由每种情况都有编译器。