Проблема с реализацией типизированных интерфейсов, которые используют друг друга - PullRequest
0 голосов
/ 20 декабря 2018

У меня есть два типизированных интерфейса

public interface IComponentAreaModel<T>
public interface IComponentAreaViewModel<T>

В интерфейсе для модели представления определено свойство 'Model', которое соответствует типу интерфейса для модели:

IComponentAreaModel<T> Model { get; }

В моей фактической реализации у меня есть модель, которая реализует интерфейс 'IComponentAreaModel', который прекрасно работает:

public class ArticleModel : IComponentAreaModel<Article>

Затем я реализую модель представления следующим образом:

public class ArticleViewModel : IComponentAreaViewModel<Article>
        {
            public ArticleModel Model { get; }
        }

И здеськомпилятор говорит мне, что у члена 'Model' нет соответствующего возвращаемого типа.Чтобы это исправить, мне нужно будет реализовать модель представления следующим образом:

public class ArticleViewModel : IComponentAreaViewModel<Article>
{
    public IComponentAreaModel<Article> Model { get; }
}

Но это отстой, так как мой класс ArticleModel имеет некоторые дополнительные методы и вещи, которые не являются частью IComponentAreaModel.Поэтому, когда я хотел использовать эти методы через свойство в моем ArticleViewModel, мне пришлось бы привести объект интерфейса к реальному объекту.

Есть ли способ сообщить компилятору, что мой ArticleModel реализует IComponentAreaModel ипоэтому достаточно в качестве модели для IComponentAreaViewModel?

1 Ответ

0 голосов
/ 20 декабря 2018

Это зависит от того, как вы используете эти интерфейсы.По крайней мере, есть три варианта.

Вариант 1. Использовать поле внутри реализации:

public class ArticleViewModel : IComponentAreaViewModel<Article>
{
    // use this field, when you need ArticleModel
    private readonly ArticleModel model;

    // TODO: initialize model somehow

    public IComponentAreaModel<Article> Model => model;
}

Вариант 2. Использовать явную реализацию интерфейса:

public class ArticleViewModel : IComponentAreaViewModel<Article>
{
    // use this property, when you need ArticleModel
    public ArticleModel Model { get; }

    IComponentAreaModel<Article> IComponentAreaViewModel<Article>.Model => Model;
}

Вариант 3Добавьте параметр второго типа для просмотра интерфейса модели.Добавит сложности, особенно если вы хотите использовать IComponentAreaViewModel<> с другими универсальными типами:

public interface IComponentAreaViewModel<T, TModel>
    where TModel : IComponentAreaModel<T>
{
    TModel Model { get; }
}

public class ArticleViewModel : IComponentAreaViewModel<Article, ArticleModel>
{
    public ArticleModel Model { get; }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...