I want to downcast interface IEntity<TM, TV, TP>
to IEntity<IModel, IView, IPresenter>
, but it gives me Invalid Cast Exception. I added some constraints (where), but it also didn't help.
Note: Im not entirely sure what is this will do, upcast or downcast in my situation
Better to show example in I try to use.
// Simple class, doesnt inherits anything.
// This class can't be generic
public class EntitiesContainer
{
private List<IEntity<IModel, IView, IPresenter>> _entities = new ();
// Adds IEntity<TM, TV, TC> to list of entities;
public void Add<TM, TV, TC>(IEntity<TM, TV, TC> entity)
where TM : IModel
where TV : IView
where TC : IPresenter
{
_entities.Add((IEntity<IModel, IView, IPresenter>)entity); // invalid cast
//or it says: argument type IEntity<TM, TV, TC> is not assignable to IEntity
//_entities.Add(entity); //syntax error
}
// some other methods below...
}
IEntity:
public interface IEntity<TM, TV, TP>
where TM : IModel
where TV : IView
where TP : IPresenter
{
TM Model { get; }
TV View { get; }
TP Presenter { get; }
}
This example I want to add IEntity to list. Class has a List of IEntity<IModel, IView, IPresenter>
, but it is a problem to add IEntity
with generic parameters. E.g. IEntity<ImplModel, ImplView, ImplPresenter
, because it can't be downcasted/upcasted to <IEntity<IModel, IView, IPresenter>>
ImplModel, ImplView, ImplPresenter- they all Implements its interfaces respectively (IModel, IView, IPresenter)
I did some research. Looks like I need to use something called generics covariance. By documentation, I need to put in or out in class. But I have List of specific generics and in or out will not help.
Any help will be helpfull. Thanks.
You can add out
specifier into your IEntity
interface declaration and then remove cast completely
class TestModel:IModel{}
class TestView:IView{}
class TestPresenter:IPresenter{}
class TestEntity : IEntity<TestModel, TestView, TestPresenter>{}
// Simple class, doesnt inherits anything.
// This class can't be generic
public class EntitiesContainer
{
private List<IEntity<IModel, IView, IPresenter>> _entities = new ();
public void Test() => Add(new TestEntity());
// Adds IEntity<TM, TV, TC> to list of entities;
public void Add(IEntity<IModel, IView, IPresenter> entity)
{
_entities.Add(entity); // not cast at all
}
// some other methods below...
}
//------->>>Main changes here - *out* TModel, etc!!!
public interface IEntity<out TModel, out TView, out TPresenter>
where TModel : IModel
where TView: IView
where TPresenter : IPresenter
{
}
public interface IPresenter{}
public interface IView{}
public interface IModel{}