I'm implementing a Repository pattern and I would like to FooRepository
to be re-usable for all models that implement IEntity
however the IDE (Rider) says that Type parameter 'IEntity' hides interface 'IEntity'
and later one causes the error message Cannot resolve symbol 'ID'
in the GetById
method.
What is the proper way to create a base class for generic types ( IEntity
in this case) that also implements an interface which takes the same generic class?
The end goal is to re-use the FooRepository
for other models (than Bar
) as the methods such as GetById
as they will mostly function the same between them.
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; }
}
I fixed your abstract class by using generics.
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; }
}
I do think a nicer (less complicated) solution is:
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; }
}
You do not need the IRepository interface because your abstract class is covering this.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.