Производный интерфейс с элементом производного интерфейса

У меня есть 2 базовых интерфейса: IViewBase (который будут реализовывать все представления) и IPresenterBase (который будут реализовывать все докладчики):

public interface IViewBase { }

public interface IPresenterBase
{
    IViewBase View { get; set; }
}

Затем я создал новый интерфейс ILogPresenter, производный от IPresenterBase, и ILogView, производный от IViewBase:

public interface ILogPresenter : IPresenterBase { }

public interface ILogView : IViewBase{ }

Когда я создаю класс, реализующий ILogPresenter,

public class LogPresenter: ILogPresenter
{
    public ILogView View { get; set; }
}

Я получаю сообщение об ошибке:

«LogPresenter» не реализует элемент интерфейса «IPresenterBase.View». «LogPresenter.View» не может реализовать «IPresenterBase.View», поскольку у него нет соответствующего возвращаемого типа «Views.IViewBase».

Я не могу установить возвращаемый тип LogPresenter.View на ILogView, производный от IViewBase? Я хотел бы реализовать ILogPresenter с другим IView, производным от IViewBase.


person Sys    schedule 04.11.2009    source источник


Ответы (2)


Вы, вероятно, захотите использовать дженерики здесь:

public interface IViewBase { }

public interface IPresenterBase<T> where T : IViewBase
{
    T View { get; set; }
}

тогда:

public interface ILogPresenter : IPresenterBase<ILogView> { }

public interface ILogView : IViewBase{ }

Помимо ковариантных возвращаемых типов, не поддерживаемых в C# (что вызвало бы проблему даже с геттером), у вас есть фундаментальная проблема в оригинале. Я мог бы сделать:

IPresenterBase foo = new LogPresenterImpl();
foo.View = new SomeOtherView();

где SomeOtherView реализовано IVewBase, но не ILogView. Как вы ожидаете, что ваша собственность справится с этим?

Приведенная выше универсальная версия решает эту проблему, позволяя докладчику выразить, какое представление он представляет.

person Jon Skeet    schedule 04.11.2009

Вы можете сделать это с помощью дженериков:

public interface IViewBase { }

public interface IPresenterBase<T> where T : IViewBase
{
    T View { get; set; }
}

public interface ILogPresenter : IPresenterBase<ILogView> { }

public interface ILogView : IViewBase { }

public class LogPresenter : ILogPresenter
{
    public ILogView View { get; set; }
}
person bruno conde    schedule 04.11.2009