C# 在泛型列表的 ForEach() 中的 lambda 表达式中使用条件运算符?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1816859/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 21:04:51  来源:igfitidea点击:

Using conditional operator in lambda expression in ForEach() on a generic List?

c#.net-3.5lambdaconditional-operator

提问by Jamezor

Is it not allowed to have a conditional operator in a lambda expression in ForEach?

在 ForEach 的 lambda 表达式中不允许有条件运算符吗?

List<string> items = new List<string>{"Item 1", "Item 2", "Item I Care About"};

string whatICareAbout = "";

// doesn't compile :(
items.ForEach(item => item.Contains("I Care About") ? 
whatICareAbout += item + "," : whatICareAbout += "");

Compilation error -> "Only assignment, call, increment, decrement, and new object expressions can be used as a statement"

编译错误->“只能将赋值、调用、递增、递减和新对象表达式用作语句”

Trying to use a normal if doesn't work either:

尝试使用正常的 if 也不起作用:

// :(
items.ForEach(item => if (item.Contains("I Care About")) {whatICareAbout += item + ", ";}

Just not possible?

只是不可能?

采纳答案by SLaks

You're using the shorter form of lambda expressions, which only allow a single expressions.
You need to the long form, which allows multiple statements.

您使用的是更短形式的 lambda 表达式,它只允许一个表达式。
您需要长格式,它允许多个语句。

For example:

例如:

items.ForEach(item => {
    if (item.Contains("I Care About")) 
        whatICareAbout += item + ", ";
});

回答by Justin Grant

Try parentheses:

尝试括号:

items.ForEach(item => item.Contains("I Care About") ? (whatICareAbout += item + ",") : (whatICareAbout += "") );

+= has a higher precedence than ?, that may be why you're getting the error. With parentheses, the error may go away. Not 100% sure of this, though... lambda expressions may have additional restrictions which prevent use of assignment statements.

+= 的优先级高于 ?,这可能是您收到错误的原因。使用括号,错误可能会消失。不是 100% 确定这一点,但是...... lambda 表达式可能有额外的限制,阻止使用赋值语句。

UPDATE:

更新:

Instead of multiple += statements, it's a lot cleaner to put the conditional on the right-hand side of the assignment, like this:

与多个 += 语句不同,将条件放在赋值语句的右侧要简洁得多,如下所示:

List<string> items = new List<string> { "one", "two", "three" };
string whatICareAbout = "";
items.ForEach(item => whatICareAbout +=  item.Contains("I Care About") ? (item + ",") : ""); 

UPDATE 2:

更新 2:

But it's even better to just use Aggregate() since it's designed for exactly this scenario. Here's one sample:

但最好只使用 Aggregate() ,因为它专为这种情况而设计。这是一个示例:

string whatICareAbout = items.Aggregate("", (total, item) => item.Contains("I Care About") ? (total + item + ",") : total);

But I think @Matt Breckon'sanswer above (that I just saw as I was about to post this)is even better than my example since it deals with removing the terminal ",". Look at his answer... :-)

但我认为上面@Matt Breckon 的回答(我刚刚看到我正要发布这个)甚至比我的例子更好,因为它涉及删除终端“,”。看看他的回答... :-)

回答by Matt Breckon

What are you trying to acheive? Are you trying to form a string of comma separated items where they contain a particular value? In linq you would achieve this using the following:

你想达到什么目的?您是否试图形成一串逗号分隔的项目,其中包含特定值?在 linq 中,您将使用以下方法实现此目的:

 List<string> items = new List<string> { "Item 1", "Item 2", "Item I Care About", "Item I Care About", "Item I Care About" }; 
 string whatICareAbout = items.Where(x => x.Contains("I Care About"))
                              .Aggregate( (y, z) => y + ", " + z);

The output from this is "Item I Care About, Item I Care About, Item I Care About".

其输出是“我关心的项目,我关心的项目,我关心的项目”。

Note: Aggregate is a great way of ensuring there is no trailing ","

注意:聚合是确保没有尾随“,”的好方法

回答by Roman Boiko

The problem was that expression

问题是那个表达

item.Contains("I Care About") ? whatICareAbout += item + "," : whatICareAbout += ""

is not a statement. It just returns a value which has type string.

不是声明。它只返回一个类型为的值string

There is a trick to make it work (just for fun):

有一个技巧可以让它工作(只是为了好玩):

    items.ForEach(item => (item.Contains("I Care About") ?
    whatICareAbout += item + "," : whatICareAbout += "").GetType());

I simply added call to .GetType()method to create a statement from initial expression, and it compiled.

我只是添加了对.GetType()方法的调用以从初始表达式创建一个语句,并编译它。