В моей программе наступил момент, когда мой полиморфизм нарушен. Я понимаю, что это в моем коде, и я понимаю, почему; Я просто не знаю, как лучше решить эту проблему.
У меня есть три модельных класса, которые имеют один и тот же интерфейс, но очень существенно разные реализации. Я создал интерфейс, а затем три независимых класса, которые также являются производными от ModelBase
класса:
public interface IMyModel
{ ... }
public class MyModelA : ModelBase, IMyModels
{ ... }
public class MyModelB : ModelBase, IMyModels
{ ... }
public class MyModelC : ModelBase, IMyModels
{ ... }
Пока все хорошо и прекрасно.
У меня есть базовый класс ViewModel, который принимает модель в качестве конструктора:
public abstract class MyViewModelBase
{
public MyViewModelBase(ModelBase Model)
this.model = Model;
}
Теперь, где я пойман; Я хочу иметь конкретный класс ViewModel, который может принимать любой из трех классов Model выше:
public class MyViewModel : MyViewModelBase
{
MyViewModel(IMyModel Model) : base (Model) // <- Invalid Polymorphism!
{
// More here
}
}
Это не работает, потому что реализация IMyModel может быть не основана на ModelBase. Аргумент не может быть безопасно передан в базовый конструктор.
Я вижу одно решение - создать абстрактный базовый класс, производный от ModelBase для этих моделей с содержимым, генерирующим исключения, и использовать его в качестве типа в моей ViewModel. Я начал с базового класса, но обнаружил, что почти в каждой части есть какая-то разница! Тем не менее, это похоже на большую работу. Кроме того, это не гарантирует, что производные классы реализуют все (как это делает интерфейс). Наконец, кажется, что это обесценивает концепцию интерфейса (более того, она мне больше не нужна).
Я не вижу способа пометить интерфейс так, чтобы он говорил, что производные классы должны иметь определенный базовый класс. Было бы хорошо, если бы я мог сделать это, но это не разрешено:
public interface IMyModel : MyModelBase
{ ... }
Есть ли лучший способ сделать это?
Пояснение:
Я, вероятно, упрощенно назвал здесь. У меня есть другие Модели и ViewModel, использующие базовые классы, но не реализующие интерфейс.
public class MyOtherModel : ModelBase // But not IMyModel!
{ ... }
public class MyOtherViewModel : MyViewModelBase
{
MyOtherViewModel(MyOtherModel Model) : base(Model) // This works
{ ... }
}