Base class 具有泛型类型,它实现了具有泛型类型的接口

Base class with a generic type which implements an interface with a generic type

我正在实施一个存储库模式,我希望 FooRepository 可重复用于所有实施 IEntity 的模型,但是 IDE (Rider) 说 Type parameter 'IEntity' hides interface 'IEntity' 和后来的一个在 GetById 方法中导致错误消息 Cannot resolve symbol 'ID'

为泛型类型(在本例中为 IEntity)创建基础 class 的正确方法是什么,它还实现了采用相同泛型 [=29] 的接口=]?

最终目标是将 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; }
}

我使用泛型修正了你的摘要 class。

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 接口,因为您的摘要 class 涵盖了它。