views:

63

answers:

1

It appears that in C# 4.0, variance specifiers are only applicable to interface types.

So let's say I have ViewModel / EditModel classes and a simple hierarchy of models.

class MyEditModel<T> where T : Base { ... }
class Derived1 : Base { ... }
class Derived2 : Base { ... }

I have a partial view that accepts a MyEditModel of any type (so long as it's derived from Base) and another one that only accepts instances of Derived1. Now how do I render both on the same page?

The partial view that accepts any MyEditModel will be shared between the editor for Derived1 and the editor for Derived2.

+1  A: 

The only has you could do this is if your view accept a view model of Base. From an OO perspective MyEditModel and Derived1 share Base as the common base class - but they don't share anything else - there is no other relationship. Hence, if you're trying to use the same then it would have to derive from Base. Presumably the properties on Base are the only ones they have in common.

Edit: I mis-interpreted the original question. Based on the literal text of your question, I thought you were passing Derived1 but base on your comment below you are passing MyEditModel<Derived1>. This will do what you're seeking:

Inherits="System.Web.Mvc.ViewPage<dynamic> 

You don't get the benefit of intellisense with dynamic - but you do get the benefit of reusing the same view file for your types and the benefit of not having to create extra view model classes just to make the compiler happy.

Steve Michelotti
The problem is that you pass MyEditModel<Derived1> or MyEditModel<Derived2> to something that accepts MyEditModel<Base>. This is only possible with interfaces.
MapDot
As for now, my lame solution involves replicating the hierarchy with EditModels... Derived1EditModel, Derived2EditModel, ... (obviously, these aren't real class names... I have PageEditModel : ContentItemEditModel and MediaFileEditModel: ContentItemEditModel. There will be more.
MapDot
@MapDot - I took your question too literally but your last comment helps clarify it - I edited my answer and verified this works.
Steve Michelotti
I kept my lame solution because I want IntelliSense, even at the expense of having some redundancy in my code. Thanks, though.
MapDot