假设我有:
- 通用方法
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 关于列表投射的这个答案。这可能是一种解决方法...