有没有办法否定谓词?

我想做这样的事情:

List list1 = ... List list2 = ... Predicate condition = ... ... list2.RemoveAll (!condition); ... list2.AddRange (list1.FindAll (condition)); 

但是,这会导致编译器错误,如! 不能应用于Predicate 。 有没有办法做到这一点?

您可以使用lambda表达式来定义一个匿名委托,它是否定谓词结果的结果:

 list.RemoveAll(x => !condition(x)); 

另外一个选项:

 static Predicate Negate(Predicate predicate) { return x => !predicate(x); } 

用法:

 // list is List some T // predicate is Predicate some T list.RemoveAll(Negate(predicate)); 

list.RemoveAll(!condition)不起作用的原因是没有! 在委托上定义的运算符。 这就是您必须根据condition定义新委托的原因,如上所示。

这实际上是可行的,但可能与您习惯的forms略有不同。 在.NET中,lambda表达式可以解释为委托OR或 表达式树 。 在表达式树上执行NOT操作相对简单。

以下是使用代码作为起点的示例:

 namespace Sample { using System; using System.Collections.Generic; using System.Linq.Expressions; internal class ExpressionSample { private static Expression Negate(Expression expression) { return Expression.Lambda(Expression.Not(expression.Body), expression.Parameters); } private static void Main() { // Match any string of length 2 or more characters Expression> expression = (s) => s.Length > 1; // Logical negation, ie match string of length 1 or fewer characters Expression> negatedExpression = ExpressionSample.Negate(expression); // Compile expressions to predicates Predicate predicate = expression.Compile(); Predicate negativePredicate = negatedExpression.Compile(); List list1 = new List { string.Empty, "an item", "x", "another item" }; List list2 = new List { "yet another item", "still another item", "y", string.Empty }; list2.RemoveAll(negativePredicate); list2.AddRange(list1.FindAll(predicate)); list2.ForEach((s) => Console.WriteLine(s)); } } }