假设我有:
- 通用方法
Get<T> - 几个接口
IEntity,IValue - 一些分别实现这些接口的类,例如:
Entity->IEntity,Value->IValue等。
=> 有没有办法Get<T>让接口只作为泛型类型?
Get<IEntity>(42); //Allowed
Get<Entity>(42); //Compiler error
我目前的解决方案如下所示:
Get<T>具有类型约束的泛型方法where T: IPersistable(以防止大多数类型作为参数传递)- 接口实现
IPersistable
该函数主动检查类型:
public T Get<T>(long id) where T : IPersistable
{
if (typeof (T) == typeof (IEntity))
return (T) EntityDao.Get(id);
if (typeof (T) == typeof (IValue))
return (T) ValueDao.Get(id);
//...
throw new TechnicalException("Type not supported");
}
=> 问题是:
- 它不干净......我可以忍受,因为只有很少的类型可供检查
- 签名与函数的实际作用不匹配。它允许输入
IPersistable,但不是真的 <-这真的让我很烦:(
编辑:我正在考虑这样的限制,以避免我的班级人数过多。
我在那个类中有 8 或 9 个通用方法,它们几乎都以这种方式工作。直观的做法是@DanielHilgarth 建议每种类型只有一种方法。目前只能用 4 或 5 种类型调用方法。但是,这仍然意味着该类中有 32-40 个方法。
如果可能的话,我想避免这种情况。
Edit2:防止调用“真实”类的需要来自协方差/逆变问题。EntityDao 和 ValueDaoGet<T>方法返回IEntity和IValue对象。当我在方法中调用集合时,当我查询单个对象失败时,什么工作正常,GetAll<T>因为我无法IEnumerable<IValue>在IEnumerable<Value>.
我刚刚注意到@JonSkeets 关于列表投射的这个答案。这可能是一种解决方法...