2012-10-31 7 views
18

Ich muss meine eigene benutzerdefinierte GenericCollection Klasse entwerfen. Jetzt habe ich viele Möglichkeiten, um es mit IEnumerable, ICollection und IList abzuleiten, wo später einige zusätzliche Funktionalitäten bietet.Benutzerdefinierte Sammlung mit IEnumerable vs ICollection vs IList

Ich bin etwas verwirrt, dass, wenn ich mit IEnumerable<T> gehe, ich das Objekt deklarieren muss, um tatsächlich die Sammlung zu halten, wie in diesem Fall _list.

public class GenericCollection<T> : IEnumerable<T> 
{ 
    private List<T> _list; 
    //... 
} 

Aber wenn ich mit ICollection<T> oder IList<T> gehen, ich erfordern nicht das List Objekt zu erklären, wie es implizit zur Verfügung steht.

public class GenericCollection<T> : IList<T> 
{ 
    // no need for List object 
    //private List<T> _list; 
    //... 
} 

Was ist der Unterschied zwischen diesen beiden Ansätzen in Bezug auf Leistung?

In welchem ​​Szenario wird man besonders bevorzugt, wenn es um die Gestaltung einer eigenen Sammlung geht. Ich bin an der leichten Kollektion mit guter Leistung interessiert. Ich denke, dass dies mit IEnumerable<T> erreicht werden kann, aber wie genau zusammen mit einigen starken Gründen, damit zu gehen?

Ich habe einige vorhandene Beiträge überprüft, aber keine gibt die erforderlichen Informationen.

Returning 'IList' vs 'ICollection' vs 'Collection'

+0

Sie müssen _list member im ersten Beispiel nicht haben. Außerdem müssen Sie noch einige Speichermechanismen implementieren, wenn Sie von IList übernehmen und die öffentliche Schnittstelle in Bezug auf IList implementieren. –

Antwort

37

IEnumerable, ICollection und IList (im Allgemeinen jede Art mit einer I prefix) sind nur interfaces. Sie können Sie zeigen, was Ihre Klasse tun wird, aber anders als wenn Sie eine Klasse, Schnittstellen bieten Ihnen keine Standard-Implementierung von den Dingen, die sie sagen, müssen Sie tun.

Soweit der Auswahl der Schnittstelle, hier ist eine kurze Anleitung:

  • Ein IList ist ein ICollection, die einen Index zugegriffen werden kann.
  • Ein ICollection ist ein IEnumerable mit einfachem Zugriff auf Dinge wie Add, Remove und Count.
  • Ein IEnumerable ist alles, was aufgezählt werden kann, auch wenn die Liste dieser Dinge nicht existiert, bis Sie es aufzählen.

Einige Klassen, die Sie (oder halten als privates Feld, das den größten Teil der Logik läuft) erweitern möchten für Ihre Sammlung sind List<T>, Collection<T>, (die IList<T> implementiert, aber mit leichteren Zugang zu Implementierung überschreiben, sehen Collection<T> versus List<T> what should you use on your interfaces? für die großen Unterschiede zwischen diesen beiden) ObservableCollection<T>, oder Sammlungen, die keine Listen sind, wie Dictionary<T, U> und HashSet<T>. Weitere Informationen zu diesen Themen finden Sie in der MSDN-Dokumentation zur Klasse.

0

Die Leistung ist unwahrscheinlich, abhängig zu sein, auf die Schnittstellen implementiert sind. Es hängt vielmehr davon ab, wie viele Anweisungen der Prozessor ausführen muss, um ein bestimmtes Ziel zu erreichen. Wenn Sie IEnumerable implementieren und die Liste umbrechen, werden Sie wahrscheinlich die Add/Remove/this [] -Methoden schreiben, die nur die Aufrufe an die Liste weiterleiten, wodurch sich ein Leistungs-Overhead ergibt. Obwohl ich keine Messungen vorgenommen habe, wäre der Vererbungsansatz wahrscheinlich sehr viel schneller.

Diese Details sind jedoch in der Regel nur für Echtzeitanwendungen wichtig, bei denen extrem viele CPU-Zyklen gespeichert werden müssen. Eric Lippert hat einen tollen Artikel über die Beachtung solcher Details: http://blogs.msdn.com/b/ericlippert/archive/2003/10/17/53237.aspx. Im Allgemeinen ist es wahrscheinlich besser, den Ansatz zu verwenden, der besser zur Geschäftslogik und Architektur Ihrer Anwendung passt als zu Leistungsdetails.

1

Zunächst müssen Sie nicht wirklich zwischen diesen Schnittstellen wählen, wenn es notwendig ist, können Sie alle drei implementieren. Zweitens müssen Sie bei der Implementierung von IEnumerable die zugrunde liegende Liste nicht veröffentlichen. Sie können nur die Methoden implementieren, die den Enumerator der zugrunde liegenden Liste verwenden.

Leistung, ich bezweifle, dass es viel Einfluss haben wird, konzentrieren Sie sich auf, was Sie funktionell brauchen. Der einzige Weg, um sicher zu sein, ist zu messen.

+0

Ich habe fälschlicherweise die öffentliche Liste hinzugefügt, danke, dass Sie darauf hingewiesen haben. Was bringt es, alle drei Schnittstellen zu implementieren? Und wenn ich mich auf die Funktionalität alleine konzentriere, dann kann ich auch mit der Liste mit hinzugefügten und bereit zu bedienenden Funktionalitäten gehen. Aber ich suche nach einigen starken Gründen für IEnumerable , wenn überhaupt? –

+0

Wenn Ilist IEnumerable implementiert, müssen Sie es nicht explizit implementieren, wenn Sie IList implementieren. Ich wollte nur sagen, dass es keine Frage ist. – Rik

Verwandte Themen