我正在编写一组LINQ 2 SQL扩展方法。目前,我有许多重复的方法,一个适用于IEnumerable集合,另一个适用于IQueryable集合。例如:
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);
}
我认为我需要这个重复的方法,因为在某些情况下我想保留IQueryable的行为,以便执行被推迟到数据库。 这是正确的假设吗?还是一个单一的IEnumerable方法(加上将输出强制转换为IQueryable)可以工作? 如果我确实需要两者,我不喜欢重复,所以我想使用通用方法将两者合并
public static T LimitVisible<T>(this T items) where T : IEnumerable<X> {
return (T)items.Where(x => !x.Hidden && !x.Parent.Hidden);
}
这个方法是可行的,但我还有其他类型(比如说Y和Z),我也想写适用于它们的LimitVisible函数。但我无法写成这样:
public static T LimitVisible<T>(this T items) where T : IEnumerable<Y> {
return (T)items.Where(y => !y.Hidden && !y.Parent.Hidden);
}
因为你可以基于泛型进行重载。我可以将这些方法放在不同的类中,但那似乎不是正确的解决方案。
有什么建议吗?也许我做出了错误的假设,根本没有必要首先创建一个特定于IQueryable的版本。
编辑:另一种选择
这是我过去使用的另一种模式,以避免重复。
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);
}
这有什么风险吗?