我正在尝试编写一个工厂方法,该方法将创建抽象泛型集合类的派生实例。这是基类......
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>
。
有人可以指出我正确的方向吗?感谢。
答案 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>
。