LINQ2SQL拡張メソッドのコレクションを書いています。現在、重複するメソッドがたくさんあります。1つはIEnumerableコレクションで動作し、もう1つは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にキャストする)が機能しますか?両方が必要な場合は、複製が気に入らないので、一般的な方法を使用して2つを結合したいと思います。
public static T LimitVisible<T>(this T items) where T : IEnumerable<X> {
return (T)items.Where(x => !x.Hidden && !x.Parent.Hidden);
}
これは、LimitVisible関数を記述したいX以外のタイプ(たとえばYとZ)があることを除いて機能します。でも書けない
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);
}
これには何か危険はありますか?