1

为什么我可以这样做?

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.
4

5 回答 5

3

因为这段代码调用了一个给定的操作(不管分支),它本身就是一个语句,因此被允许,

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

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

于 2013-10-03T00:19:32.980 回答
2

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

阅读Jon Skeet 的这个答案

于 2013-10-03T00:21:18.233 回答
1

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

于 2013-10-03T00:22:21.217 回答
1

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

var values = integerList.Direction == "ascending" ? integerList.Integers.OrderBy(i => i.IntegerValue)
                                     : integerList.Integers.OrderByDescending(i => i.IntegerValue);
于 2013-10-03T00:29:15.437 回答
0

思考 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();
于 2013-10-17T17:00:24.523 回答