三元运算符与IF THEN相比的优势是什么?

8
为什么要让事情变得更加复杂?为什么要这样做:
txtNumerator.Text = 
     txtNumerator.Text == "" ? "0" : txtNumerator.Text;

改为:

if txtNumerator.Text="" {txtNumerator.Text="0";}

8
我想你会喜欢“??”运算符。 - iandisme
5个回答

32

假设您想将零或txtNumerator.Text传递给方法M。你该怎么做?

您可以这样写:


string argument;
if (txtNumerator.Text == "")
{
    argument = "0";
}
else
{
    argument = txtNumerator.Text;
}
M(argument);

或者你可以这样说

M(txtNumerator.Text == "" ? "0" : txtNumerator.Text);

后者更短且易于阅读。 本质上,语句由于其副作用而有用,表达式由于其值而有用。如果您想要控制哪种副作用发生,则使用“if”语句。如果您想要控制从两个可能性中选择哪个值,则考虑使用条件表达式。 更新: 珍妮问为什么不只是这样做?
if (txtNumerator.Text == "")
{
    M("0");
}
else
{
    M(txtNumerator.Text);
}

如果只有一个条件要检查,那就没问题。但是如果有四个呢?现在就有十六种可能性,编写相应的“if”语句变得非常混乱:

if (text1.Text == "")
{
    if (text2.Text == "")
    {
        if (text3.Text == "")
        {
            if (text4.Text == "")
            {
                M("1", "2", "3", "4");
            }
            else
            {
                M("1", "2", "3", text4.Text);
            }
        }
        else
        {
            if (text4.Text == "")
            {
                M("1", "2", text3.Text, "4");
            }
            else
            {
                M("1", "2", text3.Text, text4.Text);
            }
        }
        ... about fifty more lines of this.

相反,您可以只是说:

M(Text1.Text == "" ? "1" : Text1.Text,
  Text2.Text == "" ? "2" : Text2.Text,
  Text3.Text == "" ? "3" : Text3.Text,
  Text4.Text == "" ? "4" : Text4.Text);

1
@jenny:好的,现在假设M还有另外三个参数,每个参数也都有一个条件值。那就有16种可能性了。你会对M进行16次不同的调用吗? - Eric Lippert
@Eric,请举出三个条件的例子。 - Alex Gordon
6
条件运算符在初始化派生类型时需要调用基类构造函数并且需要传递根据参数计算出的值时非常有用。例如,class Foo : Bar { Foo( string txt ) : base( txt == "" ? "0" : txt ) }。您也可以编写静态成员来实现这一点,但是在这种情况下使用?:更方便。 - LBushkin
5
@LBushkin提出了一个不错的观点。在C#中,有许多情况下,某个语句是不合法的,但某个表达式则是合法的。在这些情况中,您可能希望能够表达做出选择的概念,但"if"语句不可用,因为它是一个语句。 - Eric Lippert
1
@Ben:正确;C#不允许在转换为表达式树的lambda中包含语句。现在我们有一个包括语句的表达式树库,理论上我们可以这样做。只是因为构建“语句lambda”表达式树并不能启用任何新的LINQ场景,所以这并不是一个优先考虑的事项。 - Eric Lippert
显示剩余2条评论

8

这只是一个表达式,因此您可以直接在赋值或函数调用中使用结果,而无需复制使用它的上下文。这使得许多使用场景的写作和阅读变得更加清晰简洁。例如:

int abs = (x >= 0) ? x : -x;

对比

int abs;
if (x >= 0)
    abs = x;
else
    abs = -x;

3
对我来说,这是一个关键点。你可以就哪种方法更符合审美进行主观论证,很多情况都会取决于具体情境,但有能力缩短独立的声明语句和赋值语句是非常重要的。最终,三元运算符起到不同于‘if’语句的作用,因为‘if’语句用于创建单独的代码分支,而问号(?)则用于获取特定的值。 - Steven

2

有许多标准指南指出不要使用三目运算符。然而,您可能会同意除了goto和if之外,所有语言特性都是不必要的。当我有大量的if then else时,我会使用它。


2
在一些人的看法中,这使得代码更易读,语言中的许多构造都是语法糖(比如do..while、while..do和for(..)),最终你可以选择适合自己(和团队)的任何方法。
例如,我认为上述代码应该使用扩展方法来实现:
txtNumerator.SetDefault("0");

1

如果你选择使用if-then结构,你最终会在两个独立的块中对同一个变量进行两次赋值。而三元形式只有一次赋值。所以没有必要查看第二个块来确认两个块都在对同一个变量进行赋值。从这个角度上来说,我认为三元形式更易读。

另一方面,如果C#像Ruby那样if是一个表达式的话,那么你可以不用三元操作符,在这种情况下使用if-else:

txtNumerator.Text = if (txtNumerator.Text == "" ) "0"; else (txtNumerator.Text);

我更喜欢这样,因为这样就可以省略不同的 ?: 语法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接