我真正搜索了所有的协方差问题,看起来没什么问题。
我有一个用户控件(由于显而易见的原因,这个类不能通用),它看起来像这样:
class MyUserControl : UserControl
{
private BaseDao<object> _dao;
private AppointmentMapping<object> _mapping;
// I need these 2 generics to type safe the mapping/dao relation
public void RegisterPersistence<T>(BaseDao<T> dao, AppointmentMapping<T> mapping)
{
// These two dont work. even with safe and unsafe casting.
_dao = dao;
_mapping = mapping;
}
}
我已经尝试为协方差,接口等存储委托。它只是不存储对象! 我怎样才能实现这一目标?使用Java可以轻松实现这一点。
答案 0 :(得分:2)
尝试以下方法。 我们的想法是在使用时捕获T并将其存储在“知道以后要做什么”的类中。然后通过接口引用类中的项目(省略类型信息)。 稍后通过界面调用存储的值。这样,您就不需要重构通用类来实现某些接口。
class MyUserControl : UserControl
{
// hold a reference to the helper - no generics needed here -> "covariant"
private IHelper helper;
// I need this 2 generics to type safe the relation between the mapping and the dao
public void RegisterPersistence<T>(BaseDao<T> dao, AppointmentMapping<T> mapping) {
// "pass <T>" for later usage
this.helper = new HelperImpl<T>(dao, mapping);
}
// use the stored values...
public void doStuff() {
helper.doStuff();
}
// the non generic interface
private interface IHelper
{
void doStuff();
}
// a generic implementation for storing the items *and* using them.
private sealed class HelperImpl<T> : IHelper
{
private readonly BaseDao<T> dao;
private readonly AppointmentMapping<T> mapping;
public HelperImpl(BaseDao<T> dao, AppointmentMapping<T> mapping) {
this.dao = dao;
this.mapping = mapping;
}
public void doStuff() {
this.dao.foo();
this.mapping.foo();
}
}
}
答案 1 :(得分:1)
使用协方差和逆变是必要的接口!
协方差:IInterface<out T>
逆变:IInterface<in T>
检查此链接以获取更多信息: http://weblogs.asp.net/dixin/archive/2009/08/31/understanding-csharp-covariance-and-contravariance-3-samples.aspx
答案 2 :(得分:0)
据我所知,这是不可能的。
就像塞巴斯蒂安所说,你能做的就是
class MyUserControl : UserControl
{
private object _dao;
private object _mapping;
// I need this 2 generics to type safe the relation between the mapping and the dao
public void RegisterPersistence<T>(BaseDao<T> dao, AppointmentMapping<T> mapping)
{
_dao = dao;
_mapping = mapping;
}
public BaseDao<T> GetDao<T>()
{
return _dao as BaseDao<T>;
}
public AppointmentMapping<T> GetAppointmentMapping<T>()
{
return _mapping as AppointmentMapping<T>;
}
}
答案 3 :(得分:0)
H.alex是对的,最好的办法就是将通用位移到另一个层上,这样你就可以使类具有通用性,然后拥有泛型类成员而不是对象。该类必须能够推断泛型类型,或者您必须编写如下内容:
public class BaseDao<T>
{
public T Item { get; set; }
}
public class TestClass
{
private BaseDao<object> _dao;
public void RegisterPersistence<T>(BaseDao<T> dao)
{
_dao = Activator.CreateInstance<BaseDao<object>>();
//need to map each member of BaseDao
_dao.Item = dao.Item;
}
}
显然无法维护,因为您必须负责映射新实例上的所有成员。