我有以下课程:
public class Item
{
}
public class ItemCollection<TItem> : ICollection<TItem> where TItem : Item, new()
{
}
我有两个派生类:
public class Feature : Item
{
}
public class Features : ItemCollection<Feature>
{
}
我有一个经理类来管理这样的集合:
public class ItemCollectionManager<TCollection> where TCollection : ItemCollection<Item>, new()
{
}
我尝试使用这个类:
public class FeatureManager : ItemCollectionManager<Features>
{
}
但结果是:
“类型Features
必须可转换为ItemCollection<Item>
,才能在通用类ItemCollectionManager<TCollection>
中将其用作TCollection。”
如前所述,
Features
是一个ItemCollection<Feature>
和
Feature
是一个Item
。
我不认为接口是完成此任务的理想解决方案,但如果提供了原因,我愿意改变。
如果有人能就我的错误提出建议,我们将非常感激。
谢谢。
答案 0 :(得分:2)
你做不到......
ItemCollection<Feature> features = ...;
ItemCollection<Item> items = features;
这是关于泛型variance
(协方差和逆变) - 它只支持接口,代理 - 并且只提供它们的设计方式(用{{1}装饰} / in
- 并遵守随之而来的规则)。例如out
是(如果您查找其定义,则会看到IEnumerable<>
)。有关详细信息,我认为最好阅读更多...
How is Generic Covariance & Contra-variance Implemented in C# 4.0?
Understanding Covariant and Contravariant interfaces in C#
http://msdn.microsoft.com/en-us/library/dd799517.aspx
在您的情况下,您可以设计一个out
(IItemCollection<out T>
) - (理论上)可能支持您需要的投射。但它必须是interface
(有点简化而且不完全正确,但更容易这样思考 - 规则有点复杂)。
因为你将它命名为'集合',我假设它不仅仅用于枚举,查看项目 - 即如果你有read-only
种类(需要Add
- 即input parameters
)与contra-variance
所需的“协方差”冲突。此外,所涉及的任何其他参数可能都不允许您的界面变得协变。
<小时/> 我做的其他一些帖子也相关......
How to make generic class that contains a Set of only its own type or subtypes as Children?
答案 1 :(得分:1)
在ItemCollectionManager,TItem。
上需要一个额外的泛型参数我相信你的ItemCollectionManager类定义看起来应该是这样的。
public class ItemCollectionManager<TCollection, TItem> where TCollection : ItemCollection<TItem>, new(),
where TItem : Item
{
}
现在定义FeatureManager
类的方式完全可以接受Item
继承TCollection
的任何CLASS,因为TCollection
的唯一限制是它包含类型Item
的类。集合Features
仅接受继承Feature
类型的Feature
个类或类。由于您无法将Item
的基本类型添加到Features
,因此不应编译。