Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Design to avoid type casting in derived classes?

public interface IBasePresenter
{
}
public interface IJobViewPresenter : IBasePresenter
{
}
public interface IActivityViewPresenter : IBasePresenter
{
}

public class BaseView 
{
    public IBasePresenter Presenter
    {
        get;
        set;
    }
}

public class JobView : BaseView
{
    public IJobViewPresenter JobViewPresenter
    {
        get { this.Presenter as IJobViewPresenter;}
    }
}

public class ActivityView : BaseView
{
    public IActivityViewPresenter ActivityViewPresenter
    {
        get { this.Presenter as IActivityViewPresenter;}
    }
}

Lets assume that I need a IBasePresenter property on BaseView. Now this property is inherited by JobView and ActivityView but if I need reference to IJobViewPresenter object in these derived classes then I need to type cast IBasePresenter property to IJobViewPresenter or IActivityPresenter (which I want to avoid) or create JobViewPresenter and ActivityViewPresenter on derived classes (as shown above).

I want to avoid type casting in derived classes and still have reference to IJobViewPresenter or IActivityViewPresenter and still have IBasePresenter in BaseView.

Is there a way I can achieve it ?

like image 607
Deepak Avatar asked Apr 02 '10 16:04

Deepak


1 Answers

You can do this:

    public class BaseView<TPresenter>
        where TPresenter: IBasePresenter
    {
        TPresenter Presenter { get; set; }
    }

    public class JobView: BaseView<IJobViewPresenter>
    {

    }

If you have code that needs to reference BaseView, you can create an interface and expose the base presenter like this:

    public interface IBaseView
    {
        IBasePresenter BasePresenter { get; }
    }

    public class BaseView<TPresenter> : IBaseView
        where TPresenter: IBasePresenter
    {
        TPresenter Presenter { get; set; }

        IBasePresenter IBaseView.BasePresenter
        {
            get { return Presenter; }
        }
    }

Classes that need access to the BaseView can now consume the interface instead of BaseView directly. You can expose any other base services that need to be consumed in there as well.

like image 125
Dan Bryant Avatar answered Sep 22 '22 15:09

Dan Bryant