views:

54

answers:

1

I don't have much experience with generics, but can someone please explain to me why this doesn't work and what I need to do to get it to work?

I have 3 interfaces.

public interface IOnlineView

public interface ICalendarView : IOnlineView

public interface IDateView : ICalendarView

Then I have 3 presenter classes

public abstract class OnlinePresenter<T> where T : IOnlineView
{
   protected OnlinePresenter(T view) { }
}

public class CalendarPresenter<T> : OnlinePresenter<T> where T : ICalendarView
{
    public CalendarPresenter(ICalendarView view) : base(view) { }
}    

public class DatePresenter<T> : CalendarPresenter<IDateView>
{
    public DatePresenter(IDateView view) : base(view) { }
}    

The base(view) call on the CalendarPresenter class says that ICalendarView is not assignable to type T

Passing the IDateView to the CalendarPresenter works fine, but passing ICalendarView to the OnlinePresenter does not. Am I missing something? If ICalendarView inherits from IOnlineView, why can't it be passed as an argument?

This worked fine before I added the ICalendarView and CalendarPresenter between the Date and Online classes, but I need it so that the CalendarPresenter can handle the calendar display and can be inherited from other presenters.

+4  A: 

Make the following change:

public class CalendarPresenter<T> : OnlinePresenter<T> where T : ICalendarView
{
    public CalendarPresenter(T view) : base(view) { }
}  

The base class 'OnlinePresenter' constructor takes an object of type T and the sub class 'CalendarPresenter' constructor took an object of type 'ICalendarView'.

Martin Ingvar Kofoed Jensen
+1. Otherwise, you could provide `class Foo:ICalendarView` as the type parameter to `CalendarPresenter<T>`, but call the constructor with an instance of `class Bar:ICalendarView`, which would not match the `T` in the base class `OnlinePresenter<T>` (that is, `Foo`).
Ben M
+1. I thought I should have been able to use the interface since I specified it had to be of type ICalendarView. Thanks for the clarification.
Brandon