I am working on an ASP.Net MVC website and I am stuck on a getting my C# code using generics to play nice with my views.
I have a Controller that passes a Model to a View (so far so good). The Model is of type IDescribedEnumerable<T>
with some constraints on T
, among those is the constraint that T
inherits from an interface (IDescribedModel
).
I can easily write a View that accepts an IDescribedEnumerable<Country>
and that will work as long as T
is in fact the type Country
.
However, I'd also like to write a default view that accepts an IDescribedEnumerable
of <<whatever>>
and that will render it. This should be entirely possible. I don't always need to know the specific type of the Model. Often just knowing that it's an IDescribedModel
is enough.
As long as I stay in C# there is no problem. When I don't care about the specific type I just declare methods and objects as accepting a <T>
. When I do care I declare them as accepting Country
.
But:
(1) If I want to render a View I have to pick an type. I can't just say Inherits="System.Web.Mvc.ViewUserControl<IDescribedEnumerable<T>>"
I have to specify an existing type between the <>
. (even if I were to inherit from ViewUserControl
I'd have to cast it to an IDescribedEnumerable<<something>>
.
(2) Ideally I'd say that Model is IDescribedEnumerable<IDescribedModel>
in the default View and IDescribedEnumerable<Country>
in the specific implementation. However, then my Controller needs to know whether he's going to render to the default View or the specific view. It is not possible to simply cast an object that is IDescribedEnumerable<Country>
to IDescribedEnumerable<IDescribedModel>
. (IIRC it is possible in C# 4, but I'm using 3.5)
So what should I do? All options I can think of are very sub-optimal (I'm not looking forward to removing the generics and just casting objects around, nor to copy pasting the default view 65 times and keeping the copies synchoronized, nor going reflection gallore and creating an object based on a known Type
object)