I'm writing a collection of LINQ 2 SQL extension methods. Right now, I have a bunch of duplicate methods, one working on an IEnumerable collection and the other on an IQueryable collection. For example
public static IQueryable<X> LimitVisible(this IQueryable<X> items) {
return items.Where(x => !x.Hidden && !x.Parent.Hidden);
}
public static IEnumerable<X> LimitVisible(this IEnumerable<X> items) {
return items.Where(x => !x.Hidden && !x.Parent.Hidden);
}
I think I need this duplication because I want to be able to retain the IQueryable behavior in some cases, so that execution is deferred to the database. Is this a correct assumption or would a single IEnumerable method (plus casting the output to IQueryable) work? If I do need both, I don't like the duplication, so I want to combine the two using the generic method
public static T LimitVisible<T>(this T items) where T : IEnumerable<X> {
return (T)items.Where(x => !x.Hidden && !x.Parent.Hidden);
}
This works except that I have other types than X (say Y and Z) that I also want to write LimitVisible functions for. But I can't write
public static T LimitVisible<T>(this T items) where T : IEnumerable<Y> {
return (T)items.Where(y => !y.Hidden && !y.Parent.Hidden);
}
because you can overload based on generics. I could put these methods in different classes, but that doesn't seem like the right solution.
Any suggestions? Maybe I'm making incorrect assumptions and there's no need for an IQueryable specific version in the first place.
Edit: Another Option
Here's another pattern I've used in the past to avoid duplication
private static readonly Expression<Func<X, bool>> F = x => !x.Hidden && !x.Parent.Hidden;
public static IEnumerable<X> LimitVisible(this IEnumerable<X> e) {
return e.Select(W.Compile());
}
public static IQueryable<X> LimitVisible(this IQueryable<X> q) {
return q.Select(W);
}
Are there any dangers with this?
HiddenandParentproperties?