// EF (Model) project
class EntityBase { } // base class for all types
class Person : EntityBase // specific implementation for type Person
// ViewModel project
class EditableViewModel<T> where T : EntityBase // base class for all viewmodel types
class PersonViewModel : EditableViewModel<Person>
class CollectionViewModel<T> where T : EditableViewModel<EntityBase> // base class that handles CRUD operation on EditableViewModel<T> collections
// everything up to this point work. I am unable to create specific instance of CollectionViewModel<>
class AllPersonsViewModel : CollectionViewModel<PersonViewModel>
我怎样才能做到这一点?
答案 0 :(得分:1)
您来自CollectionViewModel<PersonViewModel>
,但您限制T
为EditableViewModel<EntityBase>
。 PersonViewModel
是EditableViewModel<Person>
,但它不是EditableViewModel<EntityBase>
。这两种类型是无关的。
他们为什么不相关?示例:如果B与A分配兼容,则List<B>
与List<A>
的分配不兼容。
如果您想了解更多有关此研究的信息,请参阅C#中的共同和逆变主题。
答案 1 :(得分:1)
你可以这样做:
class CollectionViewModel<TEntity, TViewModel>
where TViewModel : EditableViewModel<TEntity>
where TEntity : EntityBase
class AllPersonsViewModel : CollectionViewModel<Person, PersonViewModel>
正如我们的回答所暗示的那样,如果将类型约束为接口而不是抽象基类,则可以获得更大的灵活性;如果界面是共变或逆变,则尤其如此。
答案 2 :(得分:1)
如果您愿意使用接口而不是类,那么您可以轻松地进行协方差。以下代码编译良好:
class EntityBase { }
class Person : EntityBase {}
interface EditableViewModel<out T> where T : EntityBase {} // Must be an interface. "out" marks T as a covariant parameter
class PersonViewModel : EditableViewModel<Person> {}
class CollectionViewModel<T> where T : EditableViewModel<EntityBase> { }
class AllPersonsViewModel : CollectionViewModel<PersonViewModel> { }