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

本文关键字:运算符 三元 可以使 我可以 If 语法 Else 为什么 | 更新日期: 2023-09-27 18:33:36

为什么我可以这样做?

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.

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

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

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);

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

试试这个,

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

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

C# 中的三元运算符是运算符而不是语句。 您需要在带有某些东西的语句中使用它来接收返回值。

阅读Jon Skeet的这个答案。

因为

根据定义,三元运算符是赋值运算符,或者更准确地说是条件赋值运算符。它根据提供的条件分配不同的值。它不执行语句。虽然您绝对可以将任何三元结构展开为if-then-else构造,但反之则不然。

虽然事实仍然是三元运算符是条件赋值运算符,但您可能仍然可以这样做

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

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

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

的编译器错误的原因是语言的规则:三元运算符返回一个值。 但是值在语句中使用;它们本身不是陈述。 考虑:

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);

现在希望你对三元运算符有了更好的理解。 不幸的是,您的代码还有另一个问题。 即使这样编译,它实际上也没有做任何事情:

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();