假设我有以下类,这些类具有基于要存储的对象的不同实现:
public class ListOfPersistent<T> :
IList<T> where T : Persistent {... implementation ...}
public class ListOfNonPersistent<T> :
IList<T> {... implementation ...}
我想通过这样的方式在上面的类中使用另一个版本:
public class PersistentList<T> : IList<T> {
protected PersistentList() {
if (list != null) {
return;
}
if (Extensions.IsPersistent<T>()) {
list = new ListOfPersistent<T>();
} else {
list = new ListOfNonPersistent<T>();
}
}
protected IList<T> list;
....
}
当然上面没有编译,因为第一个类有一个类型约束而第二个类没有类型约束。有什么办法可以:告诉编译器它不应该检查这个特定情况下的约束(list = new ListOfPersistent<T>()
),因为我知道它会属于那种类型,或者做一些协方差/逆变魔术,所以代码编译时没有任何问题?
答案 0 :(得分:1)
协方差和逆变在这里对你没有帮助,因为IList<T>
是不变的。
我个人认为你的班级设计存在缺陷。您不应该想要实例化ListOfPersistent<T>
,然后将其放在类型IList<T>
不兼容的变量中。不幸的是,我不能建议一个好的选择,因为我不知道你打算如何使用这些课程或你的总体目标是什么;但我可以通过免责声明 hacky 来提出 建议,如果您真的知道自己在做什么,我们应该只使用它:
public static class ListUtils
{
public static object CreateListOfPersistent(Type elementType)
{
if (!typeof(Persistent).IsAssignableFrom(elementType))
throw new ArgumentException("elementType must derive from Persistent.", "elementType");
var listType = typeof(ListOfPersistent<>).MakeGenericType(elementType);
return Activator.CreateInstance(listType);
}
}
// ...
if (Extensions.IsPersistent<T>())
list = (IList<T>) ListUtils.CreateListOfPersistent(typeof(T));
else
list = new ListOfNonPersistent<T>();