如何将 LINQ 生成的对象的方法作为委托传递?

How to pass method on LINQ-generated object as delegate?

我有以下方法(其中 SetTypes 是一个枚举):

public IEnumerable<Chart> RetrieveCharts(IEnumerable<string> filters, SetTypes set)
{
    switch (set)
    {
        case SetTypes.Set: return GetChartsSet(filters);
        case SetTypes.Subset: return GetChartsSubset(filters);
        // Other cases here...
        default:
            throw new NotImplementedException();
    }
}

我正在跨方法调用复制代码...唯一改变的是对 HashSet 实例的方法调用:

private IEnumerable<Chart> GetChartsSet(IEnumerable<string> filters)
{
    using (var db = new ChartContext())
    {
        return db.Charts.Where(c => new HashSet<string>(c.ProductFilters.Select(f => f.Filter)).SetEquals(filters)).Select(c => c);
    }
}

private IEnumerable<Chart> GetChartsSubset(IEnumerable<string> filters)
{
    using (var db = new ChartContext())
    {
        return db.Charts.Where(c => new HashSet<string>(c.ProductFilters.Select(f => f.Filter)).IsProperSubsetOf(filters)).Select(c => c);
    }
}
// More duplicated methods follow...

我不想使用多个方法来简单地调用 HashSet 上的不同方法,而是更喜欢将 HashSet 方法作为参数的统一方法 - 但我不确定如何继续。我该怎么做?

如果你还告诉我如何去掉那个 switch 语句,加分。 :)

你可以做一个通用的实现,在集合上增加一个Predicate<HashSet<string>>

private IEnumerable<Chart> GetWithPredicate(Predicate<HashSet<string>> pred) {
    using (var db = new ChartContext()) {
        return db.Charts
            .Where(c => pred(new HashSet<string>(c.ProductFilters.Select(f => f.Filter))))
            .Select(c => c);
    }
}

然后在不同的方法中重用它:

private IEnumerable<Chart> GetChartsSet(IEnumerable<string> filters) {
    return GetWithPredicate(s => s.SetEquals(filters));
}

private IEnumerable<Chart> GetChartsSubset(IEnumerable<string> filters) {
    return GetWithPredicate(s => s.IsProperSubsetOf(filters));
}