I have come to a point in my program where my polymorphism is broken. I realize that this is in my code, and I understand why; I’m just not sure how best to resolve it.
I have three model classes which have the same interface, but very significantly different implementations. I created an interface, and then three independent classes, which also derive from a ModelBase class:
public interface IMyModel
{ ... }
public class MyModelA : ModelBase, IMyModels
{ ... }
public class MyModelB : ModelBase, IMyModels
{ ... }
public class MyModelC : ModelBase, IMyModels
{ ... }
So far fine and dandy.
I have a ViewModel base class, which takes a model as a constructor:
public abstract class MyViewModelBase
{
public MyViewModelBase(ModelBase Model)
this.model = Model;
}
Now where I am caught; I want to have a concrete ViewModel class that can accept any of the three Model classes above:
public class MyViewModel : MyViewModelBase
{
MyViewModel(IMyModel Model) : base (Model) // <- Invalid Polymorphism!
{
// More here
}
}
This doesn’t work, because it is possible for an implementation of IMyModel to not be based on ModelBase. The argument cannot be safely passed to the base constructor.
I can see one solution being to create an abstract base class derived from ModelBase for these models with exception-throwing content, and using that as the type in my ViewModel. I had started with a base class, but found that almost every part had some difference! However, that seems like a lot of work. Also, it won’t ensure that derived classes implement everything (like an interface does). Finally, it seems to devalue the interface concept (indeed, I wouldn’t need one anymore).
I don’t see any way of marking the interface as saying that derived classes must have a specific base class. It would be nice if I could do this, but it’s not allowed:
public interface IMyModel : MyModelBase
{ ... }
Is there a better way to do this?
Clarification:
I probably oversimplified the names here. I have other Models and ViewModels using the base classes, but not implementing the interface.
public class MyOtherModel : ModelBase // But not IMyModel!
{ ... }
public class MyOtherViewModel : MyViewModelBase
{
MyOtherViewModel(MyOtherModel Model) : base(Model) // This works
{ ... }
}
You could make your base class implement the interface, then inherit your implementation classes from the base class, marking the base class and methods as abstract (MustInherit/MustOverride in VB parlance). This would give you your polymorphism and guarantee the interface.