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

我该如何实现?
目前,我只对完整列表进行两次过滤,然后再组合结果。但是不幸的是,这效率很低,更重要的是我失去了原始的排序顺序,这在我的情况下是 Not Acceptable 。

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

再次,它必须是.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));

另一种选择是使用多播委托(delegate),然后使用GetInvocationList()拆分它们,然后执行相同的操作。然后,您可以执行以下操作:
List<string> filteredNames = names.FindAll(Helpers.Or(StartsWithE+StartsWithI));

不过,我不是后一种方法的忠实拥护者-感觉有点像多播的滥用。

关于c# - 合并多个谓词,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/1248232/

10-15 10:20