2

呼び出し元のクラスのジェネリック型に基づいて、2つのデータメソッドのいずれかを呼び出す必要があるアプリに取り組んでいます。たとえば、TのタイプがFooの場合、data.GetFoo()を呼び出します。

private static List<T> GetObjectList(DateTime mostRecentProcessedReadTime)
{
    using (MesReportingDal data = new MesReportingDal())
    {
        return data.GetFoo(mostRecentProcessedReadTime);  // Notice GetFoo()
    }
}

TのタイプがBarの場合、data.GetBar()を呼び出します。

private static List<T> GetObjectList(DateTime mostRecentProcessedReadTime)
{
    using (MesReportingDal data = new MesReportingDal())
    {
        return data.GetBar(mostRecentProcessedReadTime);  // Notice GetBar()
    }
}

以前は、すべてのタイプが同じ方法で取得されたため、必要なDALメソッドは1つだけでした。Tのタイプに応じて、2つのメソッドのいずれかを呼び出す必要があります。

私はこのようなことを避けようとしています:

private static List<T> GetObjectList(DateTime mostRecentProcessedReadTime)
{
    using (MesReportingDal data = new MesReportingDal())
    {
        if (T is Foo) { return data.GetFoo(mostRecentProcessedReadTime); }
        if (T is Bar) { return data.GetBar(mostRecentProcessedReadTime); }
    }
}

これはOCPに違反します。これを処理するためのエレガントな方法はありますか?それで、ifステートメントを取り除くことができますか?

編集-これはタイプがどのように見えるかです

public partial class Foo1 : IDataEntity { }
public partial class Foo2 : IDataEntity { }
public partial class Bar1 : IDataEntity { }
public partial class Bar2 : IDataEntity { }

これらのFoosandBarsは、Linq-to-SQLで使用されるDBMLアイテムです。

4

1 に答える 1

3

私は変更GetFooGetBarて、ただのようGetになりMesReportingDal、ジェネリックも作成します。

だから私はあなたがこのようなものになると思います:

private static List<T> GetObjectList(DateTime mostRecentProcessedReadTime)
{
    using (var data = new MesReportingDal<T>())
    {
        return data.Get(mostRecentProcessedReadTime);        
    }
}

ちなみに、ステートメントを使用するには、を実装usingする必要もあります。そうしないと、次のコンパイルエラーが発生します。MesReportingDalIDisposable

'MesReportingDal':usingステートメントで使用されるタイプは、暗黙的に'System.IDisposable'に変換可能である必要があります

アップデート

したがって、これについてもう少し考えてフィードバックを読んだ後、1​​つのオプションは、リポジトリインターフェイスを抽出し、作成をファクトリメソッドにプッシュバックすることです。これにより、単一のdata.Get(...)呼び出しを維持できますが、T

public interface IRepository<T> : IDisposable
{
    IList<T> Get(DateTime mostRecentRead);
}

public class FooRepo : IRepository<Foo>
{
    public IList<Foo> Get(DateTime mostRecentRead)
    {
        // Foo Implementation
    }
}

public class BarRepo : IRepository<Bar>
{
    public IList<Bar> Get(DateTime mostRecentRead)
    {
        // Bar Implemenation
    }
}

あなたの工場はこのように見えるかもしれません

public class RepositoryFactory
{
    public static IRepository<T> CreateRepository<T>()
    {
        IRepository<T> repo = null;
        Type forType = typeof(T);

        if (forType == typeof(Foo))
        {
            repo = new FooRepo() as IRepository<T>;
        }
        else if (forType == typeof(Bar))
        {
            repo = new BarRepo() as IRepository<T>;
        }

        return repo;
    }
}

そしてこれはあなたがあなたの最初のコードブロックをきれいに保つことを可能にするでしょう

private static IList<T> GetObjectList(DateTime mostRecentProcessedReadTime)
{
    using (var data = RepositoryFactory.CreateRepository<T>())
    {
        return data.Get(mostRecentProcessedReadTime);
    }
}

お役に立てば幸いです。

于 2012-04-20T13:56:15.150 に答える