否定`.Where()`LINQ表达式

时间:2017-04-25 11:09:23

标签: c# linq lambda

我知道您可以执行以下操作:

enumerable.Where(MethodGroup).DoSomething();

并且这实现了同样的目的:

enumerable.Where(x => MyMethod(x)).DoSomething();

但是,我希望实现此反转,并选择方法返回false的项目。很明显如何为第二种情况做这件事:

enumerable.Where(x => !MyMethod(x)).DoSomething();

然而,首先,情况并非如此,因为您无法将!运算符应用于MethodGroup。是否有可能以类似的方式使用.WhereNot实现这种“MethodGroups”效果,还是必须自己滚动(或使用lambdas)?

4 个答案:

答案 0 :(得分:6)

您可以创建辅助方法:

public static Func<T, bool> Not<T>(Func<T, bool> method) 
{
    return x => !method(x);
} 

然后用法与你想要的非常相似:

someEnumerable.Where(Not(MyMethod)).DoSomething();

答案 1 :(得分:2)

你可以使用Except来实现这个

<?xml version="1.0" encoding="utf-8" ?>
<root>
  <paths>
    <item>
      <name>username</name>
      <path>user/name</path>
    </item>
    <item>
      <name>useremail</name>
      <path>concat(user/name,': ',user/email)</path>
    </item>
  </paths>
  <user>
    <name>John</name>
    <email>john@gmail.com</email>
  </user>
</root>

答案 2 :(得分:2)

据我所知,没有内置方法可以做到这一点,所以要么推出自己的解决方案。或者只使用我个人认为没有错的lambda:

someList.Where(x => !MyMethod(x)).DoSomething();

这也比the other answer更好,因为它不会对集合进行两次迭代。

注意,使用lambda会使您的代码比滚动自己的方法或使用某些变通方法更明确。在这种情况下,对于像这样简单的事情,我认为最好坚持使用lambda而不是在代码中添加不必要的混淆。

答案 3 :(得分:1)

LINQ中提供的方法集没有直接的方法。即使你以某种方式实现了这一点,它也不会是一个有效的。

像你想象的那样,需要像这样做一个新的

public static IEnumerable<TSource> WhereNot<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
    return source.Where(x => !predicate(x));
}

并像

一样使用它
var inverseResult = lst.WhereNot(MyMethod);