2012-09-29 3 views
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> 

어떻게 이것을 수행 할 수 있습니까?일반 유형 인수로 일반 유형

+0

질문은 마지막 주석에 있습니다. – usr

+0

어쩌면 그는 그 코멘트를 읽을 시간이 없었을 지 모르지만 downvote 할 시간이 있었다. 그리고 그는 자신의 코멘트를 삭제하고 "ïnappropriate"을 찾아 내기로 결정했습니다. :) – Goran

답변

1

클래스 대신 인터페이스로 작업하려는 경우 쉽게 공분산을 수행 할 수 있습니다. 다음 코드는 정상적으로 컴파일됩니다.

1

CollectionViewModel<PersonViewModel>에서 파생되었지만 TEditableViewModel<EntityBase>으로 제한되었습니다. PersonViewModelEditableViewModel<Person>이지만 EditableViewModel<EntityBase>은 아닙니다. 두 유형은 서로 관련이 없습니다.

왜 관련이없는가요? 예 : B가 A와 할당 호환되는 경우 List<B>List<A>에 할당 호환되지 않습니다.

이 연구에 대해 더 자세히 알고 싶다면 C#의 공동 및 반공 변 화 항목을 참조하십시오.

+0

그래서, 제네릭 컬렉션 형식 자체에 대한 공분산을 할 수 있지만 형식 인수에서 그것을 할 수 없다는 것을 의미합니까? 이 문제를 해결할 수있는 방법이 있습니까? – Goran

+0

경험이 없으므로 달성 가능한지 확실하지 않습니다. 인터페이스 만 변형 할 수 있고 (위임 할 수 있기 때문에) 인터페이스를 도입해야합니다. 이것은 불쾌한 것으로 폭발 할 것이고 모든 역동적 인 언어 사람이 당신을 비웃을 것입니다 : "우리는 단지 컴파일러를 닥치기 위해 그런 냄새를 맡는 타입의 고약함이 필요하지 않습니다!" ;-) 아마도 이것은 권장 경로를 벗어났다는 힌트 일 수 있습니다. – usr

+0

@usr ... 또는 두 번째 유형 매개 변수를 소개 할 수 있습니다. 그런 다음 인터페이스에 대해 걱정할 필요가 없습니다 (인터페이스를 사용하면 일반적으로 더 많은 유연성이 있음). – phoog

1

당신은 따라서이를 수 있습니다 : 당신은 추상 기본 클래스보다는 인터페이스 유형을 제한하는 경우 USR의 대답에서 알 수 있듯이

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

class AllPersonsViewModel : CollectionViewModel<Person, PersonViewModel> 

, 당신은 더 많은 유연성을 얻을 것입니다; 인터페이스가 공역 또는 반 행위 일 경우 특히 그렇습니다.