如何反转一个 System.Predicate<T>?

3
假设我有一个 Predicate<T>,我想用返回 true 的谓词调用方法 foo,并且我想用返回 false 的谓词调用方法 bar,我该怎么做呢?
Predicate<int> p = i => i > 0
foo(p);
bar(!p); // obviously this doesn't work

如果谓词是一个 Func<int, bool> f,我可以使用 !f(i)

3
Predicate<T> 类似于 Func<T, bool>,所以我不觉得有什么问题... !f(i) 是正确的答案。 - xanatos
2
这不是与链接的问题重复 - 那个问题是关于创建反转表达式树的。这只涉及委托。 - Jon Skeet
1
@JonSkeet:抱歉,这个怎么样?https://dev59.com/V3I95IYBdhLWcg3www2Y - Patrick Hofman
@PatrickHofman:是的,那看起来更像是一个更好的重复。尽管我更喜欢我的扩展方法的答案 :) - Jon Skeet
@xanatos:OP的foobar方法有一个类型为Predicate<int>而不是int的参数。!p(i)p(i)的否定,产生一个int而不是Predicate<int>,因此你的建议在这种情况下不适用。 - stakx - no longer contributing
在这个与@stakx的问题相关的句子中:“如果谓词是一个Func<int,bool> f,我可以只使用!f(i)”,我的评论与该句子有关。他说他知道如何创建Func<int,bool>的否定形式,我说他也可以为Predicate<int>做同样的事情。 - xanatos
2个回答

7

您可以轻松创建一个方法来返回一个“反向”的谓词 - 您甚至可以将其制作为扩展方法:

public static Predicate<T> Invert<T>(this Predicate<T> predicate)
{
    // TODO: Nullity checking
    return x => !predicate(x);
}

然后:

bar(p.Invert());

基本上,如果你有一个Func<int, bool>,你会做的事情就是这样的-这两种委托类型都没有什么“魔法”。


这太完美了,我会在9分钟内标记为答案 :) - Luis Ferrao

1

您可以将谓词包装在lambda表达式中。

bar(x => !p(x));

抱歉,我的意思是除了被接受的答案之外。我已经从我的帖子中删除了“也”的字眼。 - Adam Prescott

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接