11

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 += "");

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

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

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

只是不可能?

4

4 回答 4

33

您正在使用较短形式的 lambda 表达式,它只允许单个表达式。
您需要长格式,它允许多个语句。

例如:

items.ForEach(item => {
    if (item.Contains("I Care About")) 
        whatICareAbout += item + ", ";
});
于 2009-11-29T21:44:05.127 回答
6

你想达到什么目的?您是否试图形成一串逗号分隔的项目,其中它们包含特定值?在 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);

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

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

于 2009-11-29T21:52:35.453 回答
4

问题是那个表达

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

不是声明。它只返回一个具有 type 的值string

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

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

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

于 2009-11-29T22:22:10.313 回答
1

试试括号:

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

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

更新:

与多个 += 语句相比,将条件放在赋值的右侧要干净得多,如下所示:

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

更新 2:

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

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

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

于 2009-11-29T21:45:03.597 回答