泛型 - C# - 没有隐式引用转换

时间:2014-08-14 06:23:39

标签: c# generics

我知道问题,但我找不到解决方案。我怎样才能创建这样的结构。什么是正确的方法?

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;
}

它使BuildingItemViewModel不能用作泛型类型或方法TVm中的类型参数ListPageViewModel<TVm>。没有从BuildingItemViewModelItemViewModel<IEntity>错误的隐式引用转换。

3 个答案:

答案 0 :(得分:2)

您需要ListPageViewModel上的第二个通用参数:

public abstract class ListPageViewModel<TVm, TModel>
    where TVm : ItemViewModel<TModel>
    where TModel : IEntity
{
}

然后,您声明了从ListPageViewModel派生的类,同时指定了TVmTModel

public class BuildingListPageViewModel
    : ListPageViewModel<BuildingItemViewModel, Building>
{
}

答案 1 :(得分:1)

ItemViewModel需要covariant。否则,ItemViewModel<Building>将不是ItemViewModel<IEntity>的子类型。

要使其协变,您需要将type参数声明为out参数,并从ItemViewModel中删除setter:

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; } }
}

答案 2 :(得分:1)

您遇到的问题是由于您已将BuildingItemViewModel创建为ItemViewModel<Building>而导致的。问题是,您希望接受ItemViewModel<IEntity>,其中IEntity是一个接口,但您的BuildingViewModel是使用具体类型Building定义的,而不是接口,因此违反了结构并给您一个错误