4

私は最高のコードの再利用性を実装しようとしています。問題は、リポジトリを介してメインプログラムからBaseAbstractクラスにあるbaseメソッドにアクセスできないことです。

以下の例を実行すると、私の状況のサンプルコードが表示されます。

だから私の質問は、メインプログラムから基本抽象クラスにあるメソッドにアクセスするにはどうすればよいかということです。

クラス/インターフェース

public abstract class BaseEntity
{
    public override abstract String ToString();
}

public abstract class BaseClass<T> where T : BaseEntity
{
    public T GetById(int id)
    {
        //Dummy Code
        return new T();
        //
    }
}

public interface IFooRepository
{
    IList<Foo> GetOrderedObjects();
}

public interface FooRepository : BaseClass<Foo>, IFooRepository
{
    public IList<Foo> GetOrderedObjects()
    {
        //GetById method is accessible from the repository - Fine
        var obj = this.GetById(5);

        //Dummy Code
        return new List<Foo>();
        //
    }
}

//メインアプリ

public class void Main()
{
    private IFooRepository _fooRepository;

    public void ProgramStartsHere()
    {
         //This is ok.
         var list = _fooRepository.GetOrderedObjects();

         //Problem is here - GetById method is not accessible from the main program through the FooRepository
         var obj = _fooRepository.GetById(10);
    }
}
4

6 に答える 6

10

GetByIdがインターフェイスで定義されていません

私は

public interface IBaseRepository<T> where T : BaseEntitiy {
 T GetById<T>(int id);
}

次にBaseClass実装しますIBaseRepository<T>

からIFooRepository継承しますIBaseRepository<Foo>

編集 :

@Olivier JDの例と同様に、GetOrderedObjectがすべてのエンティティで同じである可能性があるという考え(おそらく間違っている)を伴う完全な例。

public abstract class BaseEntity
{
    public override abstract String ToString();
}

//all generic methods
public interface IRepositoryBase<T>
    where T : BaseEntity, new()
{
    T GetById(int id);
    IList<T> GetOrderedObjects();

}

//all methods specific to foo, which can't be in a generic class
public interface IFooRepository :IRepositoryBase<Foo>
{
    void Update(Foo model);
}

//implementation of generic methods
public abstract class BaseClass<T> : IRepositoryBase<T>
    where T : BaseEntity, new() // ===> Add new() constraint here
{
    public T GetById(int id)
    {
        return new T();
    }
    public IList<T> GetOrderedObjects() {
        var obj = this.GetById(5);

        //Dummy Code
        return new List<Foo>();
        //
    }
}

//implementation of Foo specific methods
public class FooRepository : BaseClass<Foo>, IFooRepository
{
    public void Update(Foo model) {
    //bla bla
    }
}
于 2012-05-08T13:15:37.977 に答える
4

メソッドを宣言する新しいインターフェイスを追加し、GetByIdメソッドIFooRepositoryからBaseClass<T>継承します。ジェネリック型パラメーターも追加する必要がありIFooRepositoryます。(現在は一般的であるため、名前をに変更IFooRepositoryしました。)IRepository<T>

public abstract class BaseEntity
{
    public override abstract String ToString();
}

public interface IRetriever<T>
    where T : BaseEntity, new()
{
    T GetById(int id);
}

public interface IRepository<T> : IRetriever<T>
    where T : BaseEntity, new()
{
    IList<T> GetOrderedObjects();
}

public abstract class BaseClass<T> : IRetriever<T>
    where T : BaseEntity, new() // ===> Add new() constraint here
{
    public T GetById(int id)
    {
        return new T();
    }
}

public class FooRepository : BaseClass<Foo>, IRepository<Foo>
{
    public IList<Foo> GetOrderedObjects()
    {
        var obj = this.GetById(5);
        return new List<Foo>();
    }
}

これで問題なく動作します

IRepository<Foo> _fooRepository = new FooRepository();
var list = _fooRepository.GetOrderedObjects();
var obj = _fooRepository.GetById(10);
于 2012-05-08T13:38:24.890 に答える
3

_fooRepositoryから継承するIFooRepositoryので、にアクセスできませFooRepositoryGetById(10);

于 2012-05-08T13:14:33.500 に答える
3

GetByIdリポジトリインターフェースでメソッドを公開する必要があります。

public interface IFooRepository
{  
    IList<Foo> GetOrderedObjects();
    Foo GetById(int id);
}

または、RaphaëlAlthausが述べているように、型パラメーター制約を使用することもできます。

于 2012-05-08T13:43:26.043 に答える
-3

IFooRepositoryはBaseClassを継承しないため、_fooRepositoryをFooRepositoryにキャストする必要があります。次に、GetById()にアクセスできます

于 2012-05-08T13:12:36.170 に答える
-5

基本クラスにキャストします。

var obj = ((BaseClass<Foo>)_fooRepository).GetById(10);
于 2012-05-08T13:13:33.750 に答える