2013-12-10 4 views
6

Fühlen Sie sich frei, Ihre Waffen zu laden und zielen, aber ich möchte verstehen, warum Sie das nicht tun sollten.Benutzerdefiniert (abgeleitet) Liste <T>

ich eine benutzerdefinierte Klasse erstellt haben, entworfen alle Instanzen von Liste zu ersetzen (was ich zu aktualisieren XML-Objekte hinter ihnen verwenden, um):

public class ListwAddRemove<T> : List<T> { 
    public event EventHandler<ListModifyEventArgs> OnAdd; 
    public event EventHandler<ListModifyEventArgs> OnRemove; 

    new public void Add(T o) { 
     base.Add(o); 

     if (OnAdd != null) { 
      OnAdd(this, new ListModifyEventArgs(o)); 
     } 
    } 

    new public void Remove(T o) { 
     base.Remove(o); 

     if (OnRemove != null) { 
      OnRemove(this, new ListModifyEventArgs(o)); 
     } 
    } 
} 

Die Idee ist, wenn ich einen Artikel aus dieser Liste hinzuzufügen oder entfernen meine gebundene Ereignisse werden ausgelöst und ich kann automatisch mit dem XML-Code umgehen.

Das funktioniert wie ein Zauber, so weit so gut.

Aber wie handhabe ich eine Konvertierung zwischen object.ToList() und meiner abgeleiteten Version?

Viele Leute sagen, dass Sie stattdessen von Collection ableiten sollten ... warum?

+11

Haben Sie von ObservableCollection gehört? http://msdn.microsoft.com/en-au/library/ms668604(v=vs.110).aspx und http://stackoverflow.com/questions/3167752/is-there-a-way-to-convert -an-observable-collection-to-a-list – Aybe

+0

Ich benutze Windows Forms .Net 3.5 – user1830285

+0

Die Verwendung des 'new' Modifizierers zum Verstecken von Mitgliedern aus der Basisklasse ist nie eine gute Idee. Wenn Sie wirklich von 'List <>' ableiten möchten, geben Sie Ihren Methoden einige neue Namen, wie 'AddAndRaiseEvent' oder ähnliches. Allerdings ist 'List <>' class nicht wirklich für diesen Zweck gedacht. Es gibt andere Klassen, die mehr 'virtuelle' Mitglieder anbieten, die hilfreich sein sollen, wenn sie sie erben. –

Antwort

7

Sie sollen von Collection<T> ableiten, weil es Ihnen InsertItem außer Kraft zu setzen, damit angefertigt, und RemoveItem individuelle Verhalten hinzuzufügen, wie, was Sie tun (auch SetItem, kundenspezifische Verhalten hinzuzufügen, wenn ein vorhandenes Element zu ändern).

Es kann daher als IList<T> verwendet werden, und jedes Einfügen/Entfernen wird automatisch die Anpassung verwenden.

In Ihrem Fall wird jeder, der IList<T> oder die Basisklasse List<T> umsetzt, Ihre benutzerdefinierte Funktion zum Hinzufügen/Entfernen umgehen.

Collection<T> bietet auch einen Konstruktor zum Umbrechen einer vorhandenen Liste. Sie können dies von Ihrer abgeleiteten Klasse aus anzeigen, um eine von Enumerable<T>.ToList() generierte Liste umzubrechen.

UPDATE

Was ist die Syntax, um den Konstruktor zu belichten bitte?

Ganz einfach:

public class ListwAddRemove<T> : Collection<T> 
{ 
    public ListwAddRemove<T>() 
    { 
    } 

    public ListwAddRemove<T>(IList<T> list) : base(list) 
    { 
    } 

    ... implementation of overrides for InsertItem, SetItem, RemoveItem ... 
} 

Dann ist es wie folgt verwenden:

IList<SomeType> list = ....ToList(); 
ListwAddRemove<SomeType> myList = new ListwAddRemove<SomeType>(list); 
+0

Wer die "IList " -Schnittstelle ablegt, wird die neue Funktionalität verlieren, aber auch jeder, der die Basisklasse 'List ' (wie in MartinStettners Antwort) umsetzt. –

+0

"Sie können dies von Ihrer abgeleiteten Klasse aussetzen, um eine Liste zu umbrechen, die von" ... generiert wurde. Wie lautet die Syntax, um den Konstruktor freizulegen? Ich mag diese Implementierung – user1830285

+0

Es ist in Ordnung, es hat: öffentliche ListwAddRemove (Liste incomingList): base (incomingList) {} – user1830285

2

Zum einen

void DoSomeAddingToList(List<int> list) { 
    list.Add(1); 
} 

var list = new ListwAddRemove<int>(); 
DoSomeAddingToList(list); 

nicht die Ereignisse auslösen. Das kann zu merkwürdigen Effekten führen, besonders wenn Sie nicht der einzige sind, der die Klasse benutzt.

List<T> definiert ein sehr spezifisches Verhalten für Add und Remove (da es eine konkrete Klasse ist), und Benutzer können sich genau auf dieses Verhalten verlassen.

Ich denke, das ist im Allgemeinen richtig für die Verwendung eines new Modifier, so dass diese Sprachfunktion mit Vorsicht verwendet werden sollte, vor allem auf öffentliche Methoden.

Wie andere bereits erwähnt haben, ist IList<T> (Delegierung/Aggregation) wahrscheinlich die bessere Wahl.

Verwandte Themen