0
// 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>

我怎样才能做到这一点?

4

3 回答 3

1

您来自,CollectionViewModel<PersonViewModel>但您被限制TEditableViewModel<EntityBase>. PersonViewModel是一个EditableViewModel<Person>,但它不是一个EditableViewModel<EntityBase>。这两种类型是无关的。

为什么它们不相关?示例:如果 B 与 A 的赋值兼容,则List<B>与 的赋值不兼容List<A>

如果您想了解有关这项研究的更多信息,请参阅 C# 中的协变和逆变主题。

于 2012-09-29T22:07:20.083 回答
1

您可以这样实现:

class CollectionViewModel<TEntity, TViewModel>
    where TViewModel : EditableViewModel<TEntity>
    where TEntity : EntityBase

class AllPersonsViewModel : CollectionViewModel<Person, PersonViewModel> 

正如 usr 的回答所暗示的那样,如果将类型限制为接口而不是抽象基类,您将获得更大的灵活性;如果接口是协变或逆变的,则尤其如此。

于 2012-09-29T22:37:29.090 回答
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> { }
于 2012-09-29T22:58:16.950 回答