HtmlHelper <ChildType> is not assigned HtmlHelper <MotherType>

I have an idea

ViewUserControl<SearchViewData>

      

Where

SearchViewData: CommonViewData

      

In this view, I have a link to the Html.
This is the typeHtmlHelper<SearchViewData>

I am creating a custom HtmlHelper class named CommonHtmlHelper where I want this (note the type of the HtmlHelper parameter):

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

      

Since SearchViewData inherits from CommonViewData, and my Html is of type HtmlHelper <SearchViewData>, it is also HtmlHelper <CommonViewData>.
However, when I try to access the TranslatedApplicationSelectList method, in my views I get an error indicating that the HtmlHelper <SearchViewData> is not being assigned to the HtmlHelper <CommonViewData>.

Is this a flaw in my OO logic? Is this a limitation of how C # handles inheritance in generics (I think Skeet explained this to me once, but I can't find the post anymore)?

and above all how to fix it?

+2


source to share


2 answers


.NET 3.5 does not handle Covariance and Contravariance , so the only compatible typical types in .NET 3.5 are those of the same type.

One example of why this should be allowed:

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

      

Here we are simply unloading the content (i.e. reading ) from the objects, which should be safe.

The best example of why this is not allowed is :



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

      

Here we are trying to add an object BaseType

to a list that has been declared as an DerivedType

object store . This is not permitted.

Since the compiler cannot distinguish between the two cases, they are all forbidden due to this second case above.

In .NET 4.0 and C # 4.0, additional syntax will be added to indicate which direction you are allowed to convert to the generic type, depending on what you intend to do with the objects. This may cause the first of the two examples to work, but in .NET 3.5 this is not possible. The second example will not work in C # 4.0.

See here Charlie Calvert's article on Covariance and Contravariance in C # 4.0 .

+3


source


If your implementation would otherwise allow you to use HtmlHelper<SearchViewData>

where you are currently using HtmlHelper<CommonViewData>

, then you should be able to declare your extension method like this:



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

      

+1


source







All Articles