So I just wanted to follow up on my last post where I described in detail (agonizing) how I thought it sucked that Generics did not support covariance. I had pointed to Rick Byers’ post where he explained more on the matter. He commented and gave me a great idea. So I went ahead and followed his direction and came up with a solution that worked great.
In the end my solution ended up having both a generic IController as well as a non-generic IController. Big thanks to Rick again. My sample is included below. It is by no means a complete implementation but more of a conceptual model. The formatting is a bit ugly...maybe Ill fix it later...
namespace GenericVariatns
{
public interface IView
{
IController Controller { get;}
} // interface IView
} // interface IView public interface IMyTypedView : IView
{
} // interface IMyTypedView
public class MyTypedView : IView
{
#region IView<IMyTypedView> Members
public IController Controller
{ }
#endregion
} // class MyTypedView
public interface IView<vT>
where vT : IView
{
IController Controller {get;}
} // interface IMyTypedView
public interface IModel
{ } // interface IModel
public class TypedModel : IModel
{
public class TypedModel : IModel
{ } // class TypedModel public class TypedModel2 : IModel
{ } // class TypedModel2
public interface IController
{ IModel Model { get;} IController Parent { get;}
IController[] Children { get;}
IView View { get;}
} // interface IController
IController Parent { get;}
IController[] Children { get;}
IView View { get;}
} // interface IController
public interface IController<mT, vT> : IController
where mT : IModel
where vT : IView
{
mT Model { get;set;}
vT View { get;set;}
}// interface IController
public class MyControllerBase<mT, vT> : IController<mT, vT>
where mT:IModel
where vT:IView
{
# region IController<mT,vT> Members
mT _model;
public mT Model
{
get
{ return _model;} set
{_model = value; }
}
vT _view;
public vT View
{
get
{return _view; }
set
{ _view = value; }
set
{_model = value; }
}
vT _view;
public vT View
{
get
{return _view; }
set
{ _view = value; }
}
#endregion
#region IController Members
IModel IController.Model
{
get
{
return this.Model;
}
set
{
this.Model = (mT)value ;
}
}
public IController Parent
{
get { throw new Exception("The method or operation is not implemented."); }
}
public IController[] Children
{
get { throw new Exception("The method or operation is not implemented."); }
}
public IController[] Children
{
get { throw new Exception("The method or operation is not implemented."); }
} IView IController.View
{
get
{
return this.View;
}
set
{
this.View = (vT)value;
}
}
#endregion
} // class MyControllerBase
public class MyController : MyControllerBase<TypedModel, MyTypedView> //, IController<TypedModel, MyTypedView>
{
public MyController()
{ } // MyController()
//other implementation here...
} // class MyController
#endregion
} // class MyControllerBase
public class MyController : MyControllerBase<TypedModel, MyTypedView> //, IController<TypedModel, MyTypedView>
{
public MyController()
{ } // MyController()
//other implementation here...
} // class MyController
public class MyController : MyControllerBase<TypedModel, MyTypedView> //, IController<TypedModel, MyTypedView>
{
public MyController()
{ } // MyController()
//other implementation here...
} // class MyController
}