.NET - 集合和继承

发布于 2024-12-20 19:46:17 字数 601 浏览 1 评论 0原文

我有三个班级,有共同的家长。假设父母是动物,孩子是狗、猫和鹦鹉。

我有一个可观察的集合,其中包含用户正在使用的动物集合。集合包含相同类型的所有动物 - 用户只能处理所有狗或所有猫或所有鹦鹉。

因此,我声明了 ObservableCollection 动物,并根据用户的选择,我想将属性 Animals 的内容更改为 ObservableCollectionObservableCollection 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

樱娆 2024-12-27 19:46:17

它不起作用的一个原因是:如果它确实起作用,你可能会遇到无意义的情况:

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

另一个原因是,ObservableCollection 根本不是这样的情况em>继承 ObservableCollection - 它们只是不同(并行)的封闭泛型类型ObservableCollection

允许的是,某些具有“仅限输出”API 的接口(例如 IEnumerable)可以协变,因此,如果您需要迭代它们,您可以:(

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

大概在其他地方添加狗)

另一种方法是使用非通用API:

IList animals = new ObservableCollection<Dog>();

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<>.

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:

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

(presumably adding the dogs somewhere else)

Another approach would be to use a non-generic API:

IList animals = new ObservableCollection<Dog>();
把昨日还给我 2024-12-27 19:46:17

您必须将这些集合键入为 IEnumerable,而不是使用 ObservableCollection,因为 ObservableCollection 不支持类型协变。任何允许您添加元素的集合都不会支持这种类型的继承。要了解原因,请考虑这个假设的代码(它编译)

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

您可能认为这没问题,但看看如果您编写以下内容会发生什么:

myObjects.Add(new Dog());

myObjects 被声明为对象列表,因此上面的代码可以编译,但在运行时事情会崩溃,因为在幕后, myObjects 被实例化为仅保存字符串。

Instead of using ObservableCollection, you'll have to type these collections as IEnumerable<T>, since ObservableCollection 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)

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.

半世蒼涼 2024-12-27 19:46:17

如果不需要,请不要使用协方差使其变得过于复杂。
无论您是用猫、狗还是鹦鹉填充它,您都应该创建 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.

青萝楚歌 2024-12-27 19:46:17

使其成为一个接口,并使用 协方差

interface ObservableCollection <out T>
{

}

Make it an interface, and use co-variance

interface ObservableCollection <out T>
{

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文