如何在List.ForEach()中使用条件?

时间:2014-11-20 22:21:46

标签: c# .net linq list linq-to-objects

我需要从HttpSession集合中删除项目。在以下代码中,myList包含与Session相同的项目。如果myList / Session中的项目不在itemsToRemove中,则应从会话集合中删除它们。

但是,我不确定lambda语法应该是什么样子。以下内容并不正确。

myList.ForEach(x => !itemsToRemove.Contains(x) { Session.Remove(x) });

我是如何使用lambda表达式将所有内容放在一行来完成此任务的?

另外,有没有办法避免创建中间列表(myList)?我之所以这样做,是因为我无法在迭代过程中从会话中删除项目。

2 个答案:

答案 0 :(得分:7)

最天真的方式:

myList.Where(x => !itemsToRemove.Contains(x)) // LINQ extension method
      .ToList()                                                                 <----
      .ForEach(x => Session.Remove(x));       // List<T> method so this is required |

你也可以使用它:

mystList.Except(itemsToRemove)
        .ToList()
        .ForEach(x => Session.Remove(x));

但要使用ForEach,基础类型应为List<T>,因此您需要先调用ToList()。是什么导致整个集合的过度枚举。

我会这样做:

foreach (var x in mystList.Except(itemsToRemove))
{
    Session.Remove(x)
}

这将最大限度地减少枚举次数。

答案 1 :(得分:0)

首先,abatischev的回答非常好。从性能角度和可读性角度来看,它是理想的。但是,如果您真的想要将所有功能都塞进一个语句中(我不建议这样做),您可以尝试以下方法:

Session.OfType<string>()
       .Except(itemsToRemove)
       .ToList()
       .ForEach(x => Session.Remove(x));

正如abatischev所见,ToList()调用会在整个集合中花费额外的枚举,如果集合中包含大量元素,则可能会产生非常重要的性能影响。但是,这意味着ForEach()调用会迭代新创建的List<string>,它会填充您myList的角色,并允许您从会话中删除项目(因为您正在迭代该临时列表,而不是会话。)

(注意我自己没有使用HttpSessionState对象,只看了他们的MSDN文章。如果字符串不是HttpSessionState所持有的,你可能需要用其他东西替换string泛型类型。)