Derived Interface with derived interface member
Asked Answered
M

2

6

I have 2 base interfaces, IViewBase (which all views will implement) and IPresenterBase (which all presenters will implement):

public interface IViewBase { }

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

Then i've created a new interface ILogPresenter that derives from IPresenterBase and ILogView deriving from IViewBase:

public interface ILogPresenter : IPresenterBase { }

public interface ILogView : IViewBase{ }

When i create a class that implements ILogPresenter,

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

I get an error:

'LogPresenter' does not implement interface member 'IPresenterBase.View'. 'LogPresenter.View' cannot implement 'IPresenterBase.View' because it does not have the matching return type of 'Views.IViewBase'.

I cannot set the return type of LogPresenter.View to ILogView which derives from IViewBase? I would like implement ILogPresenter with a different IView which derives from IViewBase.

Marker answered 4/11, 2009 at 10:22 Comment(0)
H
9

You probably want to use generics here:

public interface IViewBase { }

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

then:

public interface ILogPresenter : IPresenterBase<ILogView> { }

public interface ILogView : IViewBase{ }

Aside from covariant return types not being supported in C# (which would cause a problem even just with a getter) you have a fundamental problem in the original. I could do:

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

where SomeOtherView implemented IVewBase but not ILogView. How would you expect your property to cope with that?

The generic version above solves this by allowing a presenter to express what kind of view it's presenting.

Hardball answered 4/11, 2009 at 10:30 Comment(0)
F
2

You can do this with generics:

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; }
}
Forefoot answered 4/11, 2009 at 10:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.