具有通用类型的基类,该基类实现具有通用类型的接口

时间:2019-01-06 14:06:10

标签: c# design-patterns repository-pattern .net-4.6.2

我正在实现存储库模式,我希望FooRepository对于实现IEntity的所有模型都可重用,但是IDE(骑士)说Type parameter 'IEntity' hides interface 'IEntity'及更高版本一种导致Cannot resolve symbol 'ID'方法中的错误消息GetById

为泛型类型(在这种情况下为IEntity)创建基类的正确方法是什么,该类也实现采用相同泛型类的接口?

最终目标是将FooRepository用于其他模型(而非Bar)作为GetById之类的方法,因为它们之间的功能大致相同。

public abstract class FooRepository<IEntity> : IRepository<IEntity>
{
    private List<IEntity> _data;

    public List<IEntity> GetAll()
    {
        return this._data;
    }

    public IEntity GetById(int id)
    {

        return this.GetAll().Single(c => c.ID == id);
    }
}

public class BarRepository : FooRepository<Bar>
{
}

public interface IEntity
{
    int ID { get; set; }
}

public interface IRepository<IEntity>
{
    List<IEntity> GetAll();
    IEntity GetById(int id);
}

public class Bar : IEntity
{
    public int ID { get; set; }
    public string Name { get; set; }
}

1 个答案:

答案 0 :(得分:1)

我使用泛型修复了您的抽象类。

public abstract class FooRepository<T> : IRepository<T> where T: IEntity
    {
        private List<T> _data;

        public List<T> GetAll()
        {
            return this._data;
        }

        T IRepository<T>.GetById(int id)
        {
            return this.GetAll().Single(c => c.ID == id);
        }
    }

    public class BarRepository : FooRepository<Bar>
    {
    }

    public interface IEntity
    {
        int ID { get; set; }
    }

    public interface IRepository<T>
    {
        List<T> GetAll();
        T GetById(int id);
    }

    public class Bar : IEntity
    {
        public int ID { get; set; }
        public string Name { get; set; }
    }

我确实认为一个更好(更简单)的解决方案是:

public abstract class FooRepository<T> where T: IEntity
    {
        private List<T> _data;

        public List<T> GetAll()
        {
            return this._data;
        }

        T GetById(int id)
        {
            return this.GetAll().Single(c => c.ID == id);
        }
    }

    public class BarRepository : FooRepository<Bar>
    {
    }

    public interface IEntity
    {
        int ID { get; set; }
    }


    public class Bar : IEntity
    {
        public int ID { get; set; }
        public string Name { get; set; }
    }

您不需要IRepository接口,因为您的抽象类涵盖了这一点。