[英]Why is my derived class not converible to base class?
I have the following classes: 我有以下课程:
public class Item
{
}
public class ItemCollection<TItem> : ICollection<TItem> where TItem : Item, new()
{
}
I have two derived classes: 我有两个派生类:
public class Feature : Item
{
}
public class Features : ItemCollection<Feature>
{
}
I have a manager class to manage such collections: 我有一个管理类来管理这样的集合:
public class ItemCollectionManager<TCollection> where TCollection : ItemCollection<Item>, new()
{
}
I tried to use this class: 我试着用这个类:
public class FeatureManager : ItemCollectionManager<Features>
{
}
but this results in: 但结果是:
"The type Features
must be convertible to ItemCollection<Item>
in order to use it as TCollection in the generic class ItemCollectionManager<TCollection>
". “类型Features
必须可转换为ItemCollection<Item>
,以便在泛型类ItemCollectionManager<TCollection>
中将其用作TCollection”。
And as previously mentioned, 如前所述,
Features
is-a ItemCollection<Feature>
Features
是一个ItemCollection<Feature>
and 和
Feature
is-a Item
. Feature
是一个Item
。
I do not believe interfaces are the ideal solution to this task but am willing to change if reason is provided. 我不相信接口是这项任务的理想解决方案,但如果提供了理由,我愿意改变。
If anyone could advise on what I'm doing wrong it would be very much appreciated. 如果有人可以就我做错的事情提出建议,我将非常感激。
Thank you. 谢谢。
You cannot do the... 你做不到......
ItemCollection<Feature> features = ...;
ItemCollection<Item> items = features;
It's about generics variance
(covariance and contravariance that is) - and it's only supported for interfaces, delegates - and only providing they're designed that way (decorated with in
/ out
- and conforming to the rules that go with it). 它是关于泛型variance
(协方差和逆variance
) - 它只支持接口,代理 - 并且只提供它们的设计方式 (用in
/ out
装饰 - 并符合随之而来的规则)。 eg IEnumerable<>
is (if you lookup its definition you'll see the out
). 例如IEnumerable<>
是(如果你查找它的定义你就会看到out
)。 For more details I think it's best to read more... 有关详细信息,我认为最好阅读更多...
How is Generic Covariance & Contra-variance Implemented in C# 4.0? 如何在C#4.0中实现通用协方差和Contra-variance?
Understanding Covariant and Contravariant interfaces in C# 理解C#中的Covariant和Contravariant接口
http://msdn.microsoft.com/en-us/library/dd799517.aspx http://msdn.microsoft.com/en-us/library/dd799517.aspx
In your case, you could design an IItemCollection<out T>
( interface
) - that ( theoretically ) might support the casting you need. 在您的情况下,您可以设计一个IItemCollection<out T>
( interface
) - ( 理论上 )可能支持您需要的转换。 But it'd have to be read-only
( a tad simplified and not entirely correct but it's easier to think that way - the rules are a bit more complex ). 但它必须是read-only
( 有点简化而且不完全正确,但更容易这样思考 - 规则有点复杂 )。
Since you're naming it a 'collection' I'm assuming it's not just for enumerating, viewing the items - ie if you have an Add
of a sort (which requires input parameters
- ie contra-variance
) that clashes with the 'covariance' you need for the upcasting
. 因为你将它命名为'集合',我假设它不仅仅用于枚举,查看项目 - 即如果你有一个类别的Add
(需要input parameters
- 即contra-variance
)与'协方差“冲突'你需要进行upcasting
。 Also any other parameters involved might not allow your interface to be made covariant. 此外,所涉及的任何其他参数可能都不允许您的界面变得协变。
How to make generic class that contains a Set of only its own type or subtypes as Children? 如何创建包含一组只有自己的类型或子类型为子类的泛型类?
C# generic handlers, what am I misunderstanding? C#泛型处理程序,我有什么误解?
You need an additional generic argument on ItemCollectionManager, TItem. 在ItemCollectionManager,TItem上需要一个额外的泛型参数。
I believe your ItemCollectionManager class definition should look something like this. 我相信你的ItemCollectionManager类定义应该是这样的。
public class ItemCollectionManager<TCollection, TItem> where TCollection : ItemCollection<TItem>, new(),
where TItem : Item
{
}
The way you have the FeatureManager
class defined right now it would be entirely acceptable to add ANY CLASS which inherits Item
to the TCollection
, since the only restriction on TCollection
is that it contains classes of type Item
. 你现在定义FeatureManager
类的方式是完全可以添加一个继承Item
到TCollection
ANY CLASS,因为对TCollection
的唯一限制是它包含Item
类型的类。 The collection Features
accepts only Feature
classes or classes which inherit the Feature
type. 集合Features
仅接受继承Feature
类型的Feature
类或类。 Since you can't add the base type of Item
to Features
, it should not compile. 既然你不能的基本类型添加Item
到Features
,它不应该编译。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.