4

我正在尝试实现最佳的代码可重用性。问题是我无法通过存储库访问位于主程序的基本抽象类中的基本方法。

如果您浏览下面的示例,您将看到我的情况的示例代码。

所以我的问题是如何从主程序访问位于基本抽象类中的方法。

类/接口

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方法并从它继承IFooRepositoryBaseClass<T>继承。您还必须添加一个泛型类型参数IFooRepository。(我重命名IFooRepositoryIRepository<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, not FooRepository,因此它无权访问GetById(10);

于 2012-05-08T13:14:33.500 回答
3

您必须在存储库接口中公开该GetById方法。

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

或者,您可以使用类型参数约束,如 Raphaël Althaus 所述

于 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 回答