2013-07-25 13 views
5

Po przejrzeniu this MSDN article, zastanawiam się teraz, jaką korzyścią jest zdefiniowanie kolekcji jako klasy dziedziczącej po ObservableCollection. Czy są jakieś znaczące różnice między tym:Kolekcja dziedzicząca z ObservableCollection - Jakie są korzyści?

class MyCollection : ObservableCollection<MyObject> { } 

class Class1 
{ 
    private MyCollection _newCollection = new MyCollection(); 

    public Class1() 
    { 
     _newCollection.Add(new MyObject()); 
    } 
} 

i tak:

class Class1 
{ 
    private ObservableCollection<MyObject> _newCollection = new ObservableCollection<MyObject>(); 

    public Class1() 
    { 
     _newCollection.Add(new MyObject()); 
    } 
} 

Czy coś mi wychodzi tutaj?

+1

Jestem trochę zdezorientowany tym, o co pytasz. Jeśli potrzebujesz dodatkowej funkcjonalności, którą można dodać do ObservableCollection przez jej rozszerzenie, napisz klasę, która ją rozszerza. Jeśli nie, możesz po prostu użyć ObservableCollection. – TheEvilPenguin

+0

Zgaduję, że w przypadku artykułu, na który patrzyłem, autor prawdopodobnie zrobił to w ten sposób ze względu na prostotę? –

+1

Alternatywą do dziedziczenia z klasy ogólnej (aby konsumenci nie musieli cały czas podawać argumentów typu ogólnego) jest użycie aliasu typu, na przykład: 'using MyCollection = ObservableCollection ;' (wadą jest to, że musisz określ to we wszystkich swoich plikach). – Dai

Odpowiedz

9

Jedną z głównych korzyści jest to, że można zdefiniować funkcję Add, która ułatwia in-line inicjalizację. Tak na przykład w ten sposób:

class MyCollection : ObservableCollection<MyObject> 
{ 
    public void Add(string prop1, string prop2) 
    { 
     base.Add(new MyObject { Prop1 = prop1, Prop2 = prop2 }); 
    } 
} 

Pozwala to napisać:

MyCollection collection = new MyCollection 
{ 
    { "prop1", "prop2" }, 
    { "prop1", "prop2" }, 
}; 

Drugi (związane) korzyści: jeśli pracujesz z XAML, o podklasy kolekcji pozwala zdefiniować przypadki Collection (dla przypadki design/test) jako znaczników, jak w:

<local:MyCollection xmlns:local="MyNamespace"> 
    <local:MyObject Prop1="prop1" Prop2="prop2" /> 
    <local:MyObject Prop1="prop1" Prop2="prop2" /> 
</local> 

wreszcie (i to jest tylko kwestia gustu, ja przypuszczam) to nie boli w ogóle, a może pomóc. Czasami potrzebujesz więcej metod/właściwości dla danego typu kolekcji. Miło mieć gotową podklasę gotową bez potrzeby refaktoryzacji.

+1

+1 dla użycia XAML, użyłem go w ten sposób z dummy klasy, która dziedziczy z 'ObservableCollection ' tylko do używania go w WPF. Jednak w XAML 2009 jest całkiem możliwe używanie natywnych klas, więc ta technika traci wartość, gdy używasz XAML poza WPF. – Alejandro

1

W podanym przykładzie nie ma żadnej szczególnej korzyści. Ogólnie uważam, że można uczciwie powiedzieć, że zazwyczaj należy unikać dziedziczenia, jeśli nie rozszerzasz lub nie nadpisujesz odziedziczonej klasy w jakiś sposób. W związku z tym twoja próbka nie jest całkiem wierna próbce z artykułu.

public class NameList : ObservableCollection<PersonName> 
{ 
    public NameList() : base() 
     { 
      Add(new PersonName("Willa", "Cather")); 
      Add(new PersonName("Isak", "Dinesen")); 
      Add(new PersonName("Victor", "Hugo")); 
      Add(new PersonName("Jules", "Verne")); 
     } 
... 

W przykładzie MSDN dodali dodatkową logikę do konstruktora klas. W rzeczywistym przykładzie na przykład ta klasa mogła mieć konstruktor, który wziąłby jakiś interfejs repozytorium lub odczytał z pliku, lub dowolną liczbę rzeczy, które nie są częścią funkcjonalności ObservableCollection Tak więc odpowiedź na twoje pierwotne pytanie jest inna pytanie "Czy chcesz przedłużyć ObservableCollection < T>?"

2

Przykład ten jest daleki od dobrego użycia w dziedziczeniu, co w szczególności nie dodaje niczego do klasy.

Zwykle można myśleć o jego podklasowaniu w taki sam sposób, jak w przypadku każdej innej klasy, gdy zapewnia ona przydatne funkcje, ale chce czegoś więcej. Możesz na przykład wykonać określoną akcję, aby wziąć wkładki, jakąś specjalną obsługę, zaimplementować dodatkowy interfejs lub inne powiadomienie, a następnie dziedziczysz i nadpisujesz/dodajesz członków zgodnie z potrzebami.

Praktyczny przykład odbywa się w ramach MVVM WPF Caliburn.Micro, gdzie mają BindableCollection<T>, dziedziczenie z ObservableCollection<T>, który wykonuje gwintu interfejsu rozrządowych w uzupełnieniu do powiadamiania o zmianach.

Powiązane problemy