1

次の 2 つのジェネリック インターフェイスの両方を実装する基本クラスを作成する方法はありますか? この基本クラスは、2 つのインターフェイスのいずれかからメソッドを呼び出すことができる「他の」クラスに継承されます。

public interface IGenericRepositoryOne<E> where E : Entity
{
    void Save(E entity);
    void Save(List<E> entityList);
    E Load(Guid entityId);
}

public interface IGenericRepositoryTwo<D, E> where E : Entity
{
    void Save(D dto);
    void Save(List<D> entityList);
    D Load(Guid entityId);
}

現在、各インターフェースを個別に実装する 2 つの個別のリポジトリがあります。

public abstract class RepositoryOne<D, E> : IGenericRepositoryOne<D, E> where E : Entity {...}

public abstract class RepositoryTWO<E> : IGenericRepositoryTwo<E> where E : Entity {...}

そして、 または のいずれRepositoryOneかを継承する必要があるクラスがありますRepositoryTwo。私が因数分解をしようとしているのは、これらのクラスです。たとえば、次のようになります。

public class MessageDataTypeRepository : RepositoryTwo<MyEntityType>
{
    // here when I call the method Load() I want it for RepositoryOne implementation.
}

public class MessageDataTypeRepository : RepositoryOne<MyDTOType, MyEntityType>
{
    // here when I call the method Load() I want it for the RepositoryTwo implementation.
}
4

2 に答える 2

3

両方のインターフェイスを実装し、明示的インターフェイスの実装を使用して一方または両方を実装できます。これにより、必要に応じて、インターフェイスごとに異なる実装を使用できます。

これが要件でない場合は、両方のインターフェイスを 1 つのジェネリック型に関して事実上同じにするため、単純に両方を実装するのは簡単です。

public class Repository<D,E> : IGenericRepositoryOne<D>, IGenericRepositoryTwo<D,E> 
    where D : Entity
    where E : Entity
{
    void Save(D dto) {}
    void Save(List<D> entityList) {}
    D Load(Guid entityId)
    {
          // Implement...
    }
}

編集:

編集した質問と実際の目標に応じて -

ここでの 1 つのオプションは、継承ではなく合成を使用することです。コンポジションを使用することで、「汎用リポジトリ」クラスが単一の意味のあるインターフェイスを公開し、適切なリポジトリを内部的に構築することができます。その後、必要に応じてメソッドを介して適切なリポジトリにマップできます。これにより、リポジトリが効果的にアダプタ パターンの実装になり、いずれかのリポジトリが共通のインターフェイスでラップされます。

于 2013-03-22T19:20:23.083 に答える
2

はい、それは可能であり、明示的なインターフェイスの実装と呼ばれています

1 つのメソッドで両方のインターフェースからメソッドを実装できます。

public void Save(D entity) { }

または別の実装:

public void IGenericRepositoryOne.Save(D entity) { }

public void IGenericRepositoryTwo.Save(D entity) { }
于 2013-03-22T19:20:32.120 に答える