c# – 组合多个谓词

在c#.NET 2.0中有什么办法吗?结合多个谓词?

假设我有以下代码。

List<string> names = new List<string>();
names.Add("Jacob");
names.Add("Emma");
names.Add("Michael");
names.Add("Isabella");
names.Add("Ethan");
names.Add("Emily");

List<string> filteredNames = names.FindAll(StartsWithE);

static bool StartsWithE(string s)
{
    if (s.StartsWith("E"))
    {
        return true;
    }
    else
    {
        return false;
    }
}

这给了我:

Emma
Ethan
Emily

所以这是很酷的东西,但我知道想要能够使用多个谓词过滤。

所以我想能够这样说:

List<string> filteredNames = names.FindAll(StartsWithE OR StartsWithI);

为了得到:

Emma
Isabella
Ethan
Emily

我该如何实现?
目前我只是过滤完整的列表两次,然后结合结果。但不幸的是,这是非常无效的,甚至更重要的是我失去了原来的排序,这在我的情况下是不能接受的。

我还需要能够遍历任何数量的过滤器/谓词,因为可能会有很多。

再次,它需要是一个.NET 2.0解决方案,不幸的是我不能使用较新版本的框架

非常感谢。

最佳答案
怎么样:

public static Predicate<T> Or<T>(params Predicate<T>[] predicates)
{
    return delegate (T item)
    {
        foreach (Predicate<T> predicate in predicates)
        {
            if (predicate(item))
            {
                return true;
            }
        }
        return false;
    };
}

为了完整性:

public static Predicate<T> And<T>(params Predicate<T>[] predicates)
{
    return delegate (T item)
    {
        foreach (Predicate<T> predicate in predicates)
        {
            if (!predicate(item))
            {
                return false;
            }
        }
        return true;
    };
}

然后调用它:

List<string> filteredNames = names.FindAll(Helpers.Or(StartsWithE, StartsWithI));

另一个选择是使用多播委托,然后使用GetInvocationList()分割它们,然后做同样的事情。然后你可以做:

List<string> filteredNames = names.FindAll(Helpers.Or(StartsWithE+StartsWithI));

我不是后一种方法的巨大粉丝 – 它感觉像是滥用多播。

转载注明原文:c# – 组合多个谓词 - 代码日志