.NET - 集合和继承
我有三个班级,有共同的家长。假设父母是动物,孩子是狗、猫和鹦鹉。
我有一个可观察的集合,其中包含用户正在使用的动物集合。集合包含相同类型的所有动物 - 用户只能处理所有狗或所有猫或所有鹦鹉。
因此,我声明了 ObservableCollection
动物,并根据用户的选择,我想将属性 Animals 的内容更改为 ObservableCollection
或 ObservableCollection
code> 或 ObservableCollection
。因此,用户当前是否与狗或猫一起工作并不重要,但他可以选择动物共有的所有动作。
但这不起作用。看来我无法将 ObservableCollection
分配给 ObservableCollection
类型的属性。我认为它应该有效,因为动物是猫的超类型,所以我可以像往常一样将猫分配给动物变量。
为什么我不能这样做以及如何解决这个问题?
I have three classes with common parent. Let's say parent is Animal and children are Dog,Cat and Parrot.
And I have one observable collection which contains collection of animals user is working with. Collection contains all animals of same type - user is either working only with all dogs or all cats or all parrots.
So I declared ObservableCollection<Animal>
animals and depending on user choices I want to change contents of property animals to ObservableCollection<Dog>
or ObservableCollection<Cat>
or ObservableCollection<PArrot>
. So it doesn't matter if user currently works with dogs or cats but he can choose all actions animals have in common.
But it doesn't work. It seems that I can't assign ObservableCollection<Cat>
to Property of type ObservableCollection<animal>
. I would think it should work, because animal is supertype of cat, so I can assign cat to animal variable as usual.
Why can't I do this and how can I solve this problem?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
它不起作用的一个原因是:如果它确实起作用,你可能会遇到无意义的情况:
另一个原因是,
ObservableCollection
根本不是这样的情况em>继承
ObservableCollection
- 它们只是不同(并行)的封闭泛型类型ObservableCollection
。允许的是,某些具有“仅限输出”API 的接口(例如
IEnumerable
)可以协变,因此,如果您需要迭代它们,您可以:(大概在其他地方添加狗)
另一种方法是使用非通用API:
One reason it doesn't work: if it did work, you could have the nonsense scenario:
Another reason is that it is simply not the case that
ObservableCollection<Dog>
inheritsObservableCollection<Animal>
- they are just different (parallel) closed generic types ofObservableCollection<>
.What is permitted is that some interfaces with "out only" APIs (such as
IEnumerable<T>
) can be covariant, so if all you need is to iterate them, you can have:(presumably adding the dogs somewhere else)
Another approach would be to use a non-generic API:
您必须将这些集合键入为
IEnumerable
,而不是使用ObservableCollection
,因为ObservableCollection
不支持类型协变。任何允许您添加元素的集合都不会支持这种类型的继承。要了解原因,请考虑这个假设的代码(它不编译)您可能认为这没问题,但看看如果您编写以下内容会发生什么:
myObjects
被声明为对象列表,因此上面的代码可以编译,但在运行时事情会崩溃,因为在幕后,myObjects
被实例化为仅保存字符串。Instead of using
ObservableCollection
, you'll have to type these collections asIEnumerable<T>
, sinceObservableCollection
does not support type covariance. No collection that allows you to add elements will ever support this type of inheritance. To see why, consider this hypothetical code (which does not compile)You'd think this would be ok, but then look what would happen if you then wrote the following:
myObjects
is declared as a List of objects, so the above code would compile, but at runtime things would blow up since, under the covers,myObjects
is instantiated to only hold strings.如果不需要,请不要使用协方差使其变得过于复杂。
无论您是用猫、狗还是鹦鹉填充它,您都应该创建
ObservableCollection
,因为您不使用任何子类化功能。您没有提到为什么使用 ObervableCollection,但如果您不观察它并且不关心列表更改的通知,您不妨对其进行转换。
Dont over-complicate it with covariance if you dont need to.
You should create
ObservableCollection<Animal>
irregardless of whether you are filling it with Cats, Dogs or Parrots since you don't use any subclassed functionality.You have not mentioned why you use ObervableCollection, but if you don't observe it and do not care about being notified of changes to the list you might as well transform it.
使其成为一个接口,并使用 协方差
Make it an interface, and use co-variance