简体   繁体   English

.NET - 集合和继承

[英].NET - Collections and inheritance

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> . 所以我声明了ObservableCollection<Animal>动物,并根据用户选择我想将属性动物的内容更改为ObservableCollection<Dog>ObservableCollection<Cat>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> . 似乎我不能将ObservableCollection<Cat>分配给ObservableCollection<animal>类型的Property。 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? 为什么我不能这样做,我该如何解决这个问题呢?

One reason it doesn't work: if it did work, you could have the nonsense scenario: 它不起作用的一个原因:如果它确实有效,你可能会有无意义的情况:

ObservableCollection<Animal> animals = new ObservableCollection<Dog>();
animals.Add(new Cat()); // cat is an animal, after all

Another reason is that it is simply not the case that ObservableCollection<Dog> inherits ObservableCollection<Animal> - they are just different (parallel) closed generic types of ObservableCollection<> . 另一个原因是,它根本就不是的情况下ObservableCollection<Dog> 继承 ObservableCollection<Animal> -它们只是不同(并行)关闭一般类型ObservableCollection<>

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: 什么允许的是,一些接口与“出只有” API(如IEnumerable<T>可以是协变的,所以如果你需要的是迭代它们,你可以有:

IEnumerable<Animal> animals = new ObservableCollection<Dog>();

(presumably adding the dogs somewhere else) (大概是狗放在其他地方)

Another approach would be to use a non-generic API: 另一种方法是使用非通用API:

IList animals = new ObservableCollection<Dog>();

Instead of using ObservableCollection , you'll have to type these collections as IEnumerable<T> , since ObservableCollection does not support type covariance. 您不必使用ObservableCollection ,而是必须将这些集合键入IEnumerable<T> ,因为ObservableCollection不支持类型协方差。 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) 要了解原因,请考虑这个假设代码( 编译)

List<object> myObjects = new List<string>();

You'd think this would be ok, but then look what would happen if you then wrote the following: 你认为这样可以,但是看看如果你写下面的内容会发生什么:

myObjects.Add(new Dog());

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. myObjects被声明为一个对象列表,因此上面的代码将被编译,但是在运行时事情会爆发,因为在myObjectsmyObjects被实例化为只保存字符串。

Make it an interface, and use co-variance 使其成为一个界面,并使用协方差

interface ObservableCollection <out T>
{

}

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. 您应该创建ObservableCollection<Animal> ,无论您是否使用Cats,Dogs或Parrots填充它,因为您不使用任何子类功能。

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. 您没有提到为什么使用ObervableCollection,但是如果您没有观察它并且不关心如何通知列表的更改,您也可以转换它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM