2009-08-05 6 views
90

próbował uruchomić Run analizy kodu w projekcie tutaj i dostał kilka ostrzeżeń, że powiedział coś takiego:C#: Różnica między Lista <T> i Collection <T> (CA1002, nie należy wystawiać listy rodzajowe)

CA1002: Microsoft.Design: Zmiana 'Wykaz < SomeType>' w 'SomeClass.SomeProtectedOrPublicProperty' do wykorzystania Collection, ReadOnlyCollection lub KeyedCollection

Wh y powinienem użyć Collection<T> zamiast List<T>? Kiedy patrzę na dokumentację msdn, wydają się prawie równe. Po przeczytaniu pomocy błędzie za ostrzeżenie, stwierdziliśmy, że

System.Collections.Generic.List (T) _is kolekcji generycznych zaprojektowanych pod kątem wydajności nie dziedziczenia, a więc nie zawiera żadnych wirtualnych członków.

Ale co to naprawdę znaczy? I co powinienem robić zamiast tego?

Czy powinienem używać wewnętrznie List<T>, a następnie we właściwościach zwrócić zamiast tego new Collection<T>(someList)? A może powinienem zacząć używać Collection<T> zamiast List<T>?

+2

Zobacz [ten wpis na blogu] (http://blogs.msdn.com/fxcop/archive/2006/04/27/585476.aspx) dla szczegółowego wyjaśnienia –

+1

Nawiasem mówiąc, jeśli chcesz wiedzieć, dlaczego Kolekcja znajduje się w [System.Collections.ObjectModel, przeczytaj to] (http://blogs.msdn.com/kcwalina/archive/2005/03/15/396086 .aspx) autorstwa Krzysztofa Cwaliny. –

Odpowiedz

127

W skrócie, ogólna lista nie zawiera wirtualnych metod dodawania, usuwania itp., Ponieważ została zaprojektowana tak, aby była szybka, nie rozszerzalna. Oznacza to, że nie możesz zamienić tej konkretnej implementacji na użyteczną podklasę (nawet jeśli możesz ją podklasować, ponieważ nie jest ona zapieczętowana).

Dlatego, ujawniając samą Listę, nie można nigdy rozszerzyć kolekcji, aby śledzić operacje dodawania lub usuwania (na przykład) bez naruszania kontraktu publicznego klasy.

Ujawniając swoją kolekcję jako IList lub coś podobnego, nadal można używać tej listy jako rzeczywistego zaplecza, ale zachowuje ona możliwość przyszłej rozbudowy, ponieważ można zamienić późniejszą implementację bez zmiany umowy publicznej klasa.

+3

Dobra odpowiedź! Ma to teraz sens: D – Svish

+5

Po prostu FYI, 'Collection ' używa wewnętrznie instancji 'List '. –

20

odsłania niektóre wirtualne elementy (wstaw, usuń, ustaw, wyczyść), które można przesłonić i zapewnić dodatkowe funkcje (takie jak zdarzenia powiadomień) po zmianie kolekcji.

Możesz nie potrzebować tego teraz, ale jest to częsty wymóg dla klas zawierających kolekcje, dlatego najlepiej zaplanować to z góry. Ponieważ Collection jest zaprojektowany z myślą o rozszerzalności, jest bardzo elastyczny. Jeśli w przyszłości zdecydujesz, że potrzebujesz dodatkowej funkcji w kolekcji, możesz po prostu ją rozszerzyć bez żadnych zmian w publicznym interfejsie klasy. Gdybyś używał listy, musiałbyś ją zmienić na kolekcję, co oznaczałoby, że zepsułoby wszystkich dzwoniących z twojej klasy, ponieważ musieliby zostać zmienieni, aby używać list.

List z drugiej strony jest zaprojektowany z myślą o wydajności, więc powinien być używany tylko w szczególnych przypadkach, gdy wydajność jest bardzo ważna. Ponieważ nie można rozszerzyć przyszłych zmian na nic, używając listy, wszystko inne będzie zależało od niej. Normalnie List powinno być używane wewnętrznie w klasach bardzo niskiego poziomu i nie powinno być narażone na cokolwiek, aby zmniejszyć prawdopodobieństwo przyszłych zmian.

Powiązane problemy