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

4

1 回答 1

1

协变和逆变在这里对您没有帮助,因为它们IList<T>是不变的。

就个人而言,我认为您的课程设计存在缺陷。您不应该实例化 aListOfPersistent<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>();
于 2011-01-27T23:20:24.233 回答