4

さまざまなタイプのオブジェクトを追加、検索、更新、および削除できる汎用リポジトリ インターフェイスを使用しています。次に、2 つの具体的なリポジトリを実装し、アプリケーションを変更せずにそれらを切り替えることができます。すべてが見事に切り離されています。しかし、私は思わぬ障害にぶつかりました。リポジトリ メソッド内のコードが間違っているように感じ、それを改善する方法がわかりません。ここに私のコードのスニペットがあります:

public class OracleRepository<T> : IRepository<T> where T : new()
{
    public IQueryable<T> GetAll()
    {
        if (typeof(T) == typeof(Object1))
        {
            return (IQueryable<T>)DataAccess.GetAllObject1().AsQueryable();

        }

        if (typeof(T) == typeof(Object2))
        {
            return (IQueryable<T>)DataAccess.GetAllObject2().AsQueryable();
        }

        throw new NotImplementedException();
    }
}

問題は、私の DataAccess (データリーダーからオブジェクトを作成する) が一般的ではなく、サポートするオブジェクトの種類ごとに特定のメソッドを持っていることです。

上記を書き直して、ジェネリックなどを使用して if-then-elseif のリストを回避できますか?

4

1 に答える 1

11

一般的なパターンの 1 つは、型から関連する型の関数への辞書を使用することです。例えば:

private static readonly IDictionary<Type, Func<object>> Fetchers =
    new Dictionary<Type, Func<object>>();
    {
        (typeof(Object1), () => DataAccess.GetAllObject1().AsQueryable()),
        (typeof(Object2), () => DataAccess.GetAllObject2().AsQueryable()),
        // etc
    };

public IQueryable<T> GetAll()
{
    Func<object> func = Fetchers[typeof(T)];
    if (func == null)
    {
        throw new NotImplementedException();
    }
    return (IQueryable<T>) func();
}

辞書で型の関係を実際に表現できないため、キャストがありますが、少なくとも新しい型などを追加する方が少し簡単です.

AsQueryable()戻り値などにGetAll()応じて、呼び出しをに移動できる場合がありますGetAllObject1()

于 2008-12-08T11:56:46.450 に答える