views:

182

answers:

3

Hi

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.

+3  A: 

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.

Jon Skeet
A: 

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; }
}
bruno conde
A: 

Thanks for the prompt answers. The above question is related to composite wpf (prism).

If anyone has experience with prism, please help me solve this: http://compositewpf.codeplex.com/WorkItem/View.aspx?WorkItemId=5414

Sys