为什么我可以使用If Else语法而不是三元运算符?

时间:2013-10-03 00:14:15

标签: c# linq if-statement ternary-operator

我为什么要这样做?

if (integerList.Direction == "ascending") { 
    integerList.Integers.OrderBy(i => i.IntegerValue);
} else{
    integerList.Integers.OrderByDescending(i => i.IntegerValue);
}

但不是吗?

integerList.Direction == "ascending" ? integerList.Integers.OrderBy(i => i.IntegerValue)
                                     : integerList.Integers.OrderByDescending(i => i.IntegerValue);

它返回错误:

only assignment, call, increment, decrement, await and new object expressions can be used as a statement.

5 个答案:

答案 0 :(得分:3)

因为此代码调用给定的操作(无论分支如何),这本身就是一个语句,因此允许,

if (integerList.Direction == "ascending") { 
    integerList.Integers.OrderBy(i => i.IntegerValue);
} else{
    integerList.Integers.OrderByDescending(i => i.IntegerValue);
}

然而,使用三元运算符,你最终得到一个表达式,它本身是不允许的,因为它被认为是无操作,当然,除了错误说,它是 new对象表达

integerList.Direction == "ascending" 
    ? integerList.Integers.OrderBy(i => i.IntegerValue)
    : integerList.Integers.OrderByDescending(i => i.IntegerValue);

操作的结果实际上并未消耗,因此浪费了整个OrderBy

试试这个,

var intergersOrdered = 
    integerList.Direction == "ascending" 
        ? integerList.Integers.OrderBy(i => i.IntegerValue)
        : integerList.Integers.OrderByDescending(i => i.IntegerValue);

将三元运算符转换为赋值语句。

答案 1 :(得分:2)

C#中的三元运算符是运算符而不是语句。您需要在声明中使用它来获取返回值。

阅读this answer by Jon Skeet

答案 2 :(得分:1)

因为根据定义,ternary operator是赋值运算符,或者更确切地说是条件赋值运算符。它根据提供的条件分配不同的值。它不会执行语句。虽然你绝对可以将任何三元构造展现为if-then-else结构,但事实并非如此。

答案 3 :(得分:1)

虽然三元运算符仍然是一个条件赋值运算符,但你可能仍然可以这样做

var values = integerList.Direction == "ascending" ? integerList.Integers.OrderBy(i => i.IntegerValue)
                                     : integerList.Integers.OrderByDescending(i => i.IntegerValue);

答案 4 :(得分:0)

考虑if-else和三元运算符之间区别的简单方法:

  • If-else允许您决定执行哪个代码
  • 三元运算符可帮助您在两个对象或值(相同类型)之间做出决定,以便在单个语句中使用

您为三元运算符收到编译器错误的原因是因为语言规则:Ternary运算符返回一个值。但是值语句中使用;他们不是自己的陈述。考虑:

int x = 1;

// Both these lines are invalid because a string literal is not a complete statement:
"x is an integer";
x < 0 ? "x is Negative" : "x is not Negative";

//Valid:
string intDescription = "x is an integer";
string describeNegative = x < 0 ? "x is Negative" : "x is not Negative";

// Invalid because the ternary operator chooses between values, and Console.WriteLine
// is void:
x < 0 ? Console.WriteLine("x is Negative") : Console.WriteLine("x is not Negative");

// Valid:
Console.WriteLine(x < 0 ? "x is Negative" : "x is not Negative");
// or:
string describeNegative = x < 0 ? "x is Negative" : "x is not Negative";
Console.WriteLine(describeNegative);

现在希望您对Ternary运算符有所了解。不幸的是,您的代码还有另一个问题。即使这个编译,它实际上并没有做任何事情:

if (integerList.Direction == "ascending") { 
    integerList.Integers.OrderBy(i => i.IntegerValue);
} else{
    integerList.Integers.OrderByDescending(i => i.IntegerValue);
}

OrderBy创建一个IOrderedEnumerable<YourIntegerClass>的新对象,其中包含Integers所做的相同内容,但已排序。 OrderBy返回此新对象并保持原始容器不变。这是Linq扩展方法的一种相对常见的模式,尽管大多数返回IEnumerable对象而不是IOrderedEnumerable。

我猜你想要对Integers的内容进行排序,而不只是制作一份你不做任何事情的副本。要做到这一点,您需要将OrderBy的结果分配回Integers对象:

if (integerList.Direction == "ascending") { 
    //I'm guessing that Integers is a List, so I've added .ToList() as well here:
    integerList.Integers = integerList.Integers.OrderBy(i => i.IntegerValue).ToList();
} else{
    integerList.Integers = integerList.Integers.OrderByDescending(i => i.IntegerValue).ToList();
}

因为您在两个值之间进行选择(在这种情况下,为了分配给Integers),您可以使用三元运算符:

integerList.Integers = integerList.Direction == "ascending" 
    ? integerList.Integers.OrderBy(i => i.IntegerValue).ToList()
    : integerList.Integers.OrderByDescending(i => i.IntegerValue).ToList();