2

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

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>

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

4

2 回答 2

6

ItemCollection CollectionBase<ItemBase>由于通用不变性,不是从 派生的。毕竟,您可以在 a 中添加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>();
于 2009-09-08T15:17:37.063 回答
3

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

于 2009-09-08T15:18:22.177 回答