Reputation: 353
I have the following method (where SetTypes is an enum):
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();
}
}
I am duplicating code across my method calls ... the only thing that's changing is the method call on the HashSet instance:
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...
Instead of having multiple methods simply to call a different method on HashSet, I'd prefer a consolidated method which takes the HashSet method as an argument - but I'm not sure how to proceed. How do I do this?
Bonus points if you also tell me how to get rid of that switch statement. :)
Upvotes: 1
Views: 57
Reputation: 726639
You could make a common implementation that takes an additional Predicate<HashSet<string>>
on the set:
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);
}
}
and then reuse it in different methods:
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));
}
Upvotes: 2