I know the problem but I couldn't find solution. How can I create such a structure. What is the correct way?
public class BuildingListPageViewModel : ListPageViewModel<BuildingItemViewModel>
{
}
public interface ItemViewModel<T> where T:IEntity
{
T Model { get; set; }
}
public abstract class ListPageViewModel<TVm> : PageViewModel where TVm : ItemViewModel<IEntity>
{
}
public class BuildingItemViewModel : ItemViewModel<Building>
{
}
public partial class Building : IEntity
{
public int Id;
}
It gives BuildingItemViewModel
cannot be used as type parameter TVm
in the generic type or method ListPageViewModel<TVm>
. There is no implicit reference conversion from BuildingItemViewModel
to ItemViewModel<IEntity>
error.
You need second generic parameter on ListPageViewModel
:
public abstract class ListPageViewModel<TVm, TModel>
where TVm : ItemViewModel<TModel>
where TModel : IEntity
{
}
Then you declare classes that derive from ListPageViewModel
with both the TVm
and TModel
specified:
public class BuildingListPageViewModel
: ListPageViewModel<BuildingItemViewModel, Building>
{
}
ItemViewModel
needs to be covariant . Otherwise, ItemViewModel<Building>
won't be a subtype of ItemViewModel<IEntity>
.
To make it covariant, you need to declare the type parameter as an out
parameter and remove the setter from ItemViewModel:
public interface ItemViewModel<out T> where T:IEntity
{
T Model { get; }
}
public class BuildingItemViewModel : ItemViewModel<Building>
{
Building b;
private BuildingItemViewModel(Building b) { this.b = b; }
public Building Model { get { return b; } }
}
The problem you are facing is caused because you have created your BuildingItemViewModel
as ItemViewModel<Building>
. The problem is, that you want to accept ItemViewModel<IEntity>
, where IEntity is an interface, but your BuildingViewModel is defined with a concrete type Building
, instead of the interface, thus violating the structure and giving you an error.
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.