Stellen Sie sich vor, ich verfüge über einen SearchService-Layer, der über eine Methode zum Suchen aller Autos verfügt, die mit einer bestimmten Zeichenfolge beginnen;
%Vor% Welche Schnittstelle sollte mein Dienst verwenden?
IQueryable kann im Rest meiner Anwendung für eine nette flüssige Schnittstelle rendern.
IEnumerable hat den trägen Aspekt dabei.
IList ist nur das Praktischste.
Ich möchte alle meine Dienste die gleiche Schnittstelle für die Konsistenz zurückgeben lassen macht die ganze Sache viel einfacher ICollection könnte vielleicht auch eine Option sein, aber es bietet nur so wenig ...
Ich würde IEnumerable
wählen, weil es eine zentrale Stelle im Framework einnimmt, Vielseitigkeit für diejenigen bietet, die es brauchen, und gleichzeitig denjenigen, die noch nicht in Sachen wie LINQ stecken bleiben, Vertrautheit vermittelt.
Meine Faustregel lautet wie folgt:
Wenn es eine Chance gibt, dass ich den Kernalgorithmus der Routine nehmen und ihn so umgestalten kann, dass ich Ertragsrenditen verwenden kann, werde ich mit IEnumerable & lt; T & gt; gehen.
Wenn beispielsweise meine aktuelle Implementierung ein Array oder eine List & lt; T & gt; intern, aber ich weiß, dass, zumindest theoretisch, ich will und in der Lage sein, es intern zu bearbeiten, um faule Bewertung zu tun, werde ich ein IEnumerable & lt; T & gt; zurückgeben.
Ich habe festgestellt, dass die Gewinne bei der Rückgabe von IEnumerable & lt; T & gt; sind definitiv die Mühe wert, es zu benutzen.
Wenn jedoch der Algorithmus in seiner Natur die Ergebnisse vollständig auswerten muss, bevor er zurückkehrt (selten, aber passiert), werde ich mit einer IList & lt; T & gt; gehen. Grundsätzlich, wenn ich es bereits berechne, werde ich es zurückgeben. IList & lt; T & gt; Implementiert IEnumerable & lt; T & gt ;, so dass alle LINQ-verwandten Anwendungsfälle immer noch funktionieren, aber Sie die faule Auswertung verlieren. Wenn ich bereits im Vorfeld gezwungen bin, das zu bewerten, ist das kein Problem.
Ich gebe selten IQueryable zurück. Die einzige Zeit, die ich diese Schnittstelle verwenden würde, ist, wenn ich direkt eine abfragbare Datenzugriffsebene oder etwas Ähnliches erstelle. Der Aufwand, dies zu verwenden, ist in den meisten Fällen die Gewinne nicht wert.
Wenn Sie jedoch immer nur eine einzige Schnittstelle verwenden möchten (ich stimme diesem Ziel nicht unbedingt zu), würde ich mich an IEnumerable & lt; T & gt;.
halten IQueryable
hätte eine ziemlich hohe Anforderung - Sie könnten zum Beispiel kein Array zurückgeben.
Normalerweise ist die Wahl zwischen IEnumerable
oder IList
normalerweise die, die im Standardfall einfacher zu implementieren ist.
Kurze Antwort: Es kommt darauf an.
Längere Antwort: Geben Sie den reichsten Typ zurück, den Ihr Client-Code benötigt. IList funktioniert in den meisten Fällen, wenn Sie kein Lazy Loading benötigen. Sie können Linq weiterhin verwenden, um eine IList oder IEnumerable abzufragen. Wenn Lazy Loading eine Voraussetzung ist, dann gehen Sie mit IEnumerable oder IQueryable.
Randnotiz: Die gleiche Schnittstelle für alle Dienste zurückzugeben, mag wie ein nobles Ziel erscheinen, aber bei unterschiedlichen Client-Nutzungsmustern können Sie verschiedene Schnittstellen zurückgeben.
Gehen Sie immer mit IEnumerable
, es sei denn, Sie haben einen ernsthaften Grund, dies nicht zu tun. Sie können den Getter dann mit yield return
implementieren.
IQueryable
ist ein ganz anderer Kessel Fisch. Nicht etwas, das Sie als Alternative zu einem typischen In-Memory-Container implementieren würden.
Der Rest ist ein großer Unterschied zwischen IEnumerable
und den anderen: es ist readonly.