1

我有以下课程:

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>才能在泛型类中用作 TCollection ItemCollectionManager<TCollection>”。

如前所述,

Features是一个ItemCollection<Feature>

Feature是一个Item

我不相信接口是完成这项任务的理想解决方案,但如果提供理由,我愿意改变。

如果有人可以就我做错了什么提出建议,将不胜感激。

谢谢你。

4

2 回答 2

2

你不能做...

ItemCollection<Feature> features = ...;
ItemCollection<Item> items = features;

它是关于泛型variance(即协变和逆变) -并且它仅支持接口、委托 - 并且仅提供它们以这种方式设计(用in/装饰out并符合随之而来的规则)。例如IEnumerable<>是(如果您查找它的定义,您会看到out)。有关更多详细信息,我认为最好阅读更多...

C# 4.0 中如何实现泛型协方差和逆变换?
了解 C# 中的协变和逆变接口
http://msdn.microsoft.com/en-us/library/dd799517.aspx

在您的情况下,您可以设计一个IItemCollection<out T>( interface) - (理论上) 可能支持您需要的转换。但它必须是read-only有点简化,并不完全正确,但这样想更容易——规则有点复杂)。

由于您将其命名为“集合”,因此我假设它不仅仅是用于枚举、查看项目 - 即,如果您有一个Add与. 此外,涉及的任何其他参数可能不允许您的界面成为协变的。 input parameterscontra-varianceupcasting


还有一些我发的其他帖子相关...

如何使泛型类包含一组仅包含其自己的类型或子类型的子类?

C# 通用处理程序,我有什么误解?

于 2013-04-02T18:52:44.533 回答
1

您需要在 ItemCollectionManager 上添加一个通用参数 TItem。

我相信您的 ItemCollectionManager 类定义应该是这样的。

    public class ItemCollectionManager<TCollection, TItem> where TCollection : ItemCollection<TItem>, new(), 
where TItem : Item
    {
    }

FeatureManager现在定义类的方式完全可以接受添加继承Item到的任何类TCollection,因为唯一的限制TCollection是它包含类型的类Item。该集合Features仅接受Feature类或继承该Feature类型的类。由于您不能添加Itemto的基本类型Features,因此它不应该编译。

于 2013-04-02T18:22:20.410 回答