C# - 如何从工厂方法创建继承的通用集合
我正在尝试编写一个工厂方法来创建抽象通用集合类的派生实例。这是基类……
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
派生的。
有人可以指出我正确的方向吗?谢谢。
I am trying to write a factory method that will create a derived instance of an abstract generic collection class. Here are the base classes ...
abstract class ItemBase { }
abstract class CollectionBase<T> : Collection<T> where T : ItemBase, new() { }
...and their derived classes ...
class Item : ItemBase { }
class ItemCollection : CollectionBase<Item> {}
Now, I want a factory method that will create an ItemCollection. But note that the derived classes Item and ItemCollection are unknown to the class that contains this factory method. This is how I imagine it should be ...
static T CreateItemCollection<T>() where T : CollectionBase<ItemBase>, new()
{
return new T();
}
... and I imagine invoking it thus ...
var collection = CreateItemCollection<ItemCollection>();
But the factory method won't compile because ItemBase must have a parameterless constructor. And the invokation call refuses to believe that ItemCollection
is derived from CollectionBase<ItemBase>
.
Can someone please point me in the right direction? Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
由于通用不变性,
ItemCollection
不是派生自CollectionBase
。毕竟,您可以将ItemBase
添加到CollectionBase
- 但您不希望将其用于您的ItemCollection
!您需要使方法在两个类型参数中通用:
只有集合类型需要无参数构造函数。你可以这样称呼它:
ItemCollection
isn't derived fromCollectionBase<ItemBase>
, due to generic invariance. After all, you can add anItemBase
to aCollectionBase<ItemBase>
- but you don't want that for yourItemCollection
!You need to make the method generic in two type parameters:
Only the collection type needs a parameterless constructor. You'd call this with:
这里的问题是通用约束,在 C# 3.0 中,对于方差有任何余地。相反,匹配相当严格。由于 ItemCollection 派生自
CollectionBase
,因此不被视为派生自CollectionBase
,即使类型可能看起来兼容。The problem here is generic constraints, in C# 3.0, have any leeway with regards to variance. The matching is instead fairly strict. Since ItemCollection derives from
CollectionBase<Item>
it is not considered to be derived fromCollectionBase<ItemBase>
even though the types may appear to be compatible.