[英]Is there any way to negate a Predicate?
我想做这样的事情:
List<SomeClass> list1 = ...
List<SomeClass> list2 = ...
Predicate<SomeClass> condition = ...
...
list2.RemoveAll (!condition);
...
list2.AddRange (list1.FindAll (condition));
但是,这会导致编译器错误,如!
不能应用于Predicate<SomeClass>
。 有没有办法做到这一点?
您可以使用lambda表达式来定义一个匿名委托,它是否定谓词结果的结果:
list.RemoveAll(x => !condition(x));
另外一个选项:
static Predicate<T> Negate<T>(Predicate<T> predicate) {
return x => !predicate(x);
}
用法:
// list is List<T> some T
// predicate is Predicate<T> some T
list.RemoveAll(Negate(predicate));
list.RemoveAll(!condition)
不起作用的原因是没有!
在委托上定义的运算符。 这就是您必须根据condition
定义新委托的原因,如上所示。
这实际上是可能的,但可能与您习惯的形式略有不同。 在.NET中,lambda表达式可以解释为委托OR或 表达式树 。 在表达式树上执行NOT
操作相对简单。
以下是使用代码作为起点的示例:
namespace Sample
{
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
internal class ExpressionSample
{
private static Expression<TDelegate> Negate<TDelegate>(Expression<TDelegate> expression)
{
return Expression.Lambda<TDelegate>(Expression.Not(expression.Body), expression.Parameters);
}
private static void Main()
{
// Match any string of length 2 or more characters
Expression<Predicate<string>> expression = (s) => s.Length > 1;
// Logical negation, i.e. match string of length 1 or fewer characters
Expression<Predicate<string>> negatedExpression = ExpressionSample.Negate(expression);
// Compile expressions to predicates
Predicate<string> predicate = expression.Compile();
Predicate<string> negativePredicate = negatedExpression.Compile();
List<string> list1 = new List<string> { string.Empty, "an item", "x", "another item" };
List<string> list2 = new List<string> { "yet another item", "still another item", "y", string.Empty };
list2.RemoveAll(negativePredicate);
list2.AddRange(list1.FindAll(predicate));
list2.ForEach((s) => Console.WriteLine(s));
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.