2011-01-27 35 views
0

比方说,我已经被存储在具有基于对象的不同实现以下类:类型参数,约束和协方差/逆变

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>()),因为我知道它会是这种类型的,或者做一些协变/逆变魔术,所以代码编译没有任何问题?

回答

1

协变和逆变将不会帮助你,因为IList<T>是不变的。

我个人认为你的班级设计存在缺陷。您不应该想要实例化一个ListOfPersistent<T>,然后将其放置在类型为IList<T>的变量不兼容的变量中。不幸的是,我不能提出一个好的选择,因为我不知道你打算如何使用这些课程或你的总体目标是什么;但我可以让一个建议,并声明这是哈克和也许应该,如果你真的知道你在做什么,只能用于:

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>(); 
+0

两个班做同样的事情,但由于内工作是完全不同的,其中一个取决于类型是持久性的,这就是为什么有两个类。当然,如果......在其中一门课上,我可以做很多事情,但这很难保持,并且不是很快。基本上,PersistentList只是一个装饰器,因为它没有任何功能,只是使用IList的下划线功能,这又取决于T的类型是否为Persistent,需要两种不同的实现。 – CheloXL 2011-01-28 01:58:17