[英].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
被聲明為一個對象列表,因此上面的代碼將被編譯,但是在運行時事情會爆發,因為在myObjects
, myObjects
被實例化為只保存字符串。
使其成為一個界面,並使用協方差
interface ObservableCollection <out T>
{
}
如果你不需要,不要用協方差使它過於復雜。 您應該創建ObservableCollection<Animal>
,無論您是否使用Cats,Dogs或Parrots填充它,因為您不使用任何子類功能。
您沒有提到為什么使用ObervableCollection,但是如果您沒有觀察它並且不關心如何通知列表的更改,您也可以轉換它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.