2009-09-16 5 views
2

제가Html 헬퍼 할당되지 <ChildType>는 <MotherType>

SearchViewData: CommonViewData 

이보기에서는 I 따라서 HTML로 참조가 도면

ViewUserControl<SearchViewData> 

Html 헬퍼가있다.
이 (Html ​​헬퍼 매개 변수의 유형을주의) HtmlHelper<SearchViewData>

은 내가이 원하는 CommonHtmlHelper라는 사용자 지정 Html 헬퍼 클래스를 만드는 유형이다 : SearchViewData이 CommonViewData에서 상속 때문에

public static SelectList TranslatedApplicationSelectList(this HtmlHelper<CommonViewData> htmlHelper, string selectedCode) 

을 내 HTML은이다 형식 HtmlHelper < SearchViewData> 따라서 HtmlHelper < CommonViewData>입니다.
그러나 TranslatedApplicationSelectList 메서드에 액세스하려고하면 내 뷰에서 HtmlHelper < SearchViewData>를 HtmlHelper에 할당 할 수 없다는 오류가 발생합니다. < CommonViewData>.

내 OO 논리에 결함이 있습니까? 이것은 C#이 제네릭에서 상속을 처리하는 방법의 한계입니까 (Skeet이 내게 이것을 설명했지만 더 이상 해당 게시물을 찾을 수 없음).

그리고 무엇보다도 어떻게 수정해야합니까?

답변

3

.NET 3.5는 Covariance and Contravariance을 처리하지 않으므로 .NET 3.5의 유일한 일반 유형은 정확히 동일한 유형의 것입니다. 이 허용되어야하는 이유

한 예 : 여기

public class BaseType { } 
public class DerivedType : BaseType { } 

public void DumpList(List<BaseType> list) 
{ 
    foreach (var o in list) 
     Debug.WriteLine(o); 
} 

... 
List<DerivedType> objects = new List<DerivedType>(); 
objects.Add(new DerivedType()); 
DumpList(objects); 

우리는 단순히 내용을 덤프 안전하도록되어있는 개체에서 (. 즉 읽기).

이 이유의 더 나은 예를

허용되지 : 여기

public class BaseType { } 
public class DerivedType : BaseType { } 

public void ManipulateList(List<BaseType> list) 
{ 
    list.Add(new BaseType()); 
} 

... 
List<DerivedType> objects = new List<DerivedType>(); 
objects.Add(new DerivedType()); 
ManipulateList(objects); 

우리가 DerivedType 객체를 포함하기로 선언 된 목록에 BaseType의 객체를 추가하려고하고 있습니다. 허용되지 않습니다.

컴파일러는 두 가지 경우를 구분할 수 없기 때문에 위의 두 번째 경우 때문에 컴파일러가 모두 허용되지 않습니다.

.NET 4.0 및 C# 4.0에서는 개체를 사용하여 수행 할 작업에 따라 일반 형식을 변환 할 수있는 방향을 지정하는 추가 구문을 적용 할 수 있습니다. 이렇게하면 두 예제 중 첫 번째 예제가 작동하지만 .NET 3.5에서는 이것이 불가능합니다. 두 번째 예제는 C# 4.0에서는 작동하지 않습니다.

여기는 Covariance and Contravariance in C# 4.0에 대한 Charlie Calvert의 기사입니다.

+0

예, 사람들이했던 일을 설명 John Skeet에 의해 나에게 일찍부터. 나는 이것이 내 문제의 이유라고 느꼈지만 확신 할 수 없었고 조건을 모르고서 다시 질문을 찾을 수 없었다. 그래서 내 문제에 대한 유일한 해결책은 HtmlHelper 를 허용하는 메소드를 작성하고 다른 유형에서이를 수행하려는 경우 다른 메소드를 작성하는 것입니다. S generic 유형을 "캐스팅"하는 구문도 없습니다 받아 들일 수 있을까요? 정규 캐스트와 마찬가지로 프로그래머에게 책임을 물을 것입니다. –

1

당신의 implmentation 그렇지 않으면 당신이 현재 HtmlHelper<CommonViewData>을 사용하는 곳에 당신이 HtmlHelper<SearchViewData>를 사용할 수 있도록한다면, 당신은 대신이 같은 확장 방법을 선언 할 수 있어야한다 :

public static SelectList TranslatedApplicationSelectList<T>(this HtmlHelper<T> htmlHelper, string selectedCode) where T : CommonViewData 
+0

그건 실제로 내가하고있는 일이지만, 다른 뷰가 viewdata로 사용되는 다른 뷰에서 메서드를 재사용 할 수 없다는 것을 의미합니다. –

+0

@boris - 확장 메소드가 일반이기 때문에 왜 그런지 이해할 수 없습니다. 하위 클래스와 함께 사용할 수 있습니다. – kvb