C# - 如何从工厂方法创建继承的泛型集合

时间:2009-09-08 15:13:38

标签: c# constraints factory generic-collections

我正在尝试编写一个工厂方法,该方法将创建抽象泛型集合类的派生实例。这是基类......

abstract class ItemBase { }

abstract class CollectionBase<T> : Collection<T> where T : ItemBase, new() { }

......及其派生类......

class Item : ItemBase { }

class ItemCollection : CollectionBase<Item> {}

现在,我想要一个将创建ItemCollection的工厂方法。但请注意,派生类Item和ItemCollection对于包含此工厂方法的类是未知的。这就是我想象的应该......

static T CreateItemCollection<T>() where T : CollectionBase<ItemBase>, new()
{
    return new T();
}

...我想像这样调用它......

var collection = CreateItemCollection<ItemCollection>();

但是工厂方法不会编译,因为ItemBase必须具有无参数构造函数。并且调用调用拒绝相信ItemCollection来自CollectionBase<ItemBase>

有人可以指出我正确的方向吗?感谢。

2 个答案:

答案 0 :(得分:6)

由于通用不变性,

ItemCollection 不是派生自CollectionBase<ItemBase>。毕竟,您可以向ItemBase添加CollectionBase<ItemBase> - 但您不希望ItemCollection支持static T CreateItemCollection<TCollection, TItem>() where TCollection : CollectionBase<TItem>, new() where TItem : ItemBase { return new TCollection(); }

您需要在两个类型参数中使该方法通用:

var collection = CreateItemCollection<ItemCollection, Item>();

只有集合类型需要无参数构造函数。你打电话给:

{{1}}

答案 1 :(得分:3)

这里的问题是泛型约束,在C#3.0中,有关于方差的任何余地。相反,匹配相当严格。由于ItemCollection派生自CollectionBase<Item>,因此即使类型出现兼容,也不会认为它来自CollectionBase<ItemBase>