Here's a short example of the issue I'm encountering
I have two abstract classes EntityAbs and ListEntityAbs :
public abstract class EntityAbs {
//Save itself in a Database
public abstract int SaveEntity();
}
public abstract class ListEntitiesAbs<T> where T : EntityAbs {
protected List<T> InnerList;
//Save each values in a Database
public virtual int SaveEntities()
{
return InnerList.Sum(entity => entity.SaveEntity());
}
}
Multiple classes that herits on EntityAbs and get it's own ListEntities (an example with a class named Item) :
public class Item : EntityAbs {
public override int SaveEntity()
{
// Implements here how I save it
}
}
public class Items : ListEntitiesAbs<Item>, IList<Item> {
// Has specific class stuff in it
}
Now, I would like to save every ListEntitiesAbs somewhere else on my database
public int Save(params ListEntitiesAbs<EntityAbs>[] lists)
{
for(int i = 0; i < lists.Length; i++)
lists[i].SaveEntities();
}
Items items = new Items();
// add items
int result = Save(items);
But then, items (or any other list I add here) displays an error by Visual Studio, and I don't here why.
The error says that it Cannot convert from Items to ListEntitiesAbs<EntityAbs>
, but Items herits from ListEntitiesAbs and Item from EntityAbs..
Am I missing something ? I've tried casting as ListEntityAbs or using Cast<> but nothing fits
Any help is appreciated, as I'm not even sure if this kind of behavior is actually possible
Well ListEntitiesAbs<T>
is not covariant. This means that ListEntitiesAbs<Item>
is not, and cannot be trivially converted to, ListEntitiesAbs<EntityAbs>
.
Option 1: make Save
generic
public int Save<T>(params ListEntitiesAbs<T>[] lists) where T:EntityAbs
{
for(int i = 0; i < lists.Length; i++)
lists[i].SaveEntities();
}
Option 2: non generic interface. You could also make a covariant interface, but that does not seem to be needed in this particular case.
public interface IListEntitiesAbs {
public int SaveEntities();
}
public int Save(params IListEntitiesAbs[] lists){
...
}