簡體   English   中英

.NET - 集合和繼承

[英].NET - Collections and inheritance

我有三個共同父母的課程。 讓我們說父母是動物,孩子是狗,貓和鸚鵡。

我有一個可觀察的集合,其中包含用戶正在使用的動物集合。 收集包含所有相同類型的動物 - 用戶只能與所有狗或所有貓或所有鸚鵡一起工作。

所以我聲明了ObservableCollection<Animal>動物,並根據用戶選擇我想將屬性動物的內容更改為ObservableCollection<Dog>ObservableCollection<Cat>ObservableCollection<PArrot> 因此,如果用戶目前與狗或貓一起工作並不重要,但他可以選擇動物共有的所有動作。

但它不起作用。 似乎我不能將ObservableCollection<Cat>分配給ObservableCollection<animal>類型的Property。 我認為它應該有用,因為動物是貓的超類型,所以我可以像往常一樣將貓分配給動物變量。

為什么我不能這樣做,我該如何解決這個問題呢?

它不起作用的一個原因:如果它確實有效,你可能會有無意義的情況:

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

另一個原因是,它根本就不是的情況下ObservableCollection<Dog> 繼承 ObservableCollection<Animal> -它們只是不同(並行)關閉一般類型ObservableCollection<>

什么允許的是,一些接口與“出只有” API(如IEnumerable<T>可以是協變的,所以如果你需要的是迭代它們,你可以有:

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

(大概是狗放在其他地方)

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

IList animals = new ObservableCollection<Dog>();

您不必使用ObservableCollection ,而是必須將這些集合鍵入IEnumerable<T> ,因為ObservableCollection不支持類型協方差。 沒有允許您添加元素的集合將支持這種類型的繼承。 要了解原因,請考慮這個假設代碼( 編譯)

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

你認為這樣可以,但是看看如果你寫下面的內容會發生什么:

myObjects.Add(new Dog());

myObjects被聲明為一個對象列表,因此上面的代碼將被編譯,但是在運行時事情會爆發,因為在myObjectsmyObjects被實例化為只保存字符串。

使其成為一個界面,並使用協方差

interface ObservableCollection <out T>
{

}

如果你不需要,不要用協方差使它過於復雜。 您應該創建ObservableCollection<Animal> ,無論您是否使用Cats,Dogs或Parrots填充它,因為您不使用任何子類功能。

您沒有提到為什么使用ObervableCollection,但是如果您沒有觀察它並且不關心如何通知列表的更改,您也可以轉換它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM