So bin ich heute auf ein interessantes Problem gestoßen. Wir haben einen WCF-Webdienst, der eine IList zurückgibt. Nicht wirklich eine große Sache, bis ich es sortieren wollte.
Es stellt sich heraus, dass in der IList-Schnittstelle keine Sortiermethode integriert ist.
Am Ende benutzte ich die ArrayList.Adapter(list).Sort(new MyComparer())
Methode, um das Problem zu lösen, aber es schien mir nur ein bisschen "Ghetto" zu sein.
Ich spielte mit dem Schreiben einer Erweiterungsmethode, auch mit dem Erben von IList und dem Implementieren meiner eigenen Sort () -Methode sowie dem Casting in eine Liste, aber keine davon schien übermäßig elegant.
Meine Frage ist also, ob jemand eine elegante Lösung zum Sortieren einer IList hat
Antworten:
Wie wäre es mit LINQ To Objects, um für Sie zu sortieren?
Angenommen, Sie haben eine
IList<Car>
, und das Auto hatte eineEngine
Eigenschaft, ich glaube, Sie könnten wie folgt sortieren:Bearbeiten: Sie müssen schnell sein, um hier Antworten zu erhalten. Da ich eine etwas andere Syntax als die anderen Antworten angegeben habe, werde ich meine Antwort belassen. Die anderen Antworten sind jedoch gleichermaßen gültig.
quelle
Sie können LINQ verwenden:
quelle
Diese Frage hat mich dazu inspiriert, einen Blog-Beitrag zu schreiben: http://blog.velir.com/index.php/2011/02/17/ilistt-sorting-a-better-way/
Ich denke, dass .NET Framework im Idealfall eine statische Sortiermethode enthält, die eine IList <T> akzeptiert, aber das nächstbeste ist, eine eigene Erweiterungsmethode zu erstellen. Es ist nicht allzu schwierig, einige Methoden zu erstellen, mit denen Sie eine IList <T> wie eine Liste <T> sortieren können. Als Bonus können Sie die LINQ OrderBy-Erweiterungsmethode mit derselben Technik überladen, sodass Sie unabhängig von List.Sort, IList.Sort oder IEnumerable.OrderBy genau dieselbe Syntax verwenden können.
Sortieren Sie mit diesen Erweiterungen Ihre IList wie eine Liste:
Weitere Informationen finden Sie im Beitrag: http://blog.velir.com/index.php/2011/02/17/ilistt-sorting-a-better-way/
quelle
ISortableList<T>
Schnittstelle anzubieten (mit Methoden zum Sortieren eines Teils der Liste unter Verwendung eines bestimmten Vergleichers), sie zuList<T>
implementieren und eine statische Methode zu haben, die jede sortieren könnte,IList<T>
indem geprüft wird, ob sie implementiert ist,ISortableList<T>
und wenn nicht, Kopieren Sie es in ein Array, sortieren Sie es, löschen Sie esIList<T>
und fügen Sie die Elemente erneut hinzu.IList<T> list
auf die nicht generischeIList
Schnittstelle übertragen werden kann. Wenn Sie Ihre eigene Klasse codieren, die dieIList<T>
Schnittstelle implementiert , stellen Sie sicher, dass Sie auch die nicht generischeIList
Schnittstelle implementieren. Andernfalls schlägt der Code mit einer Klassenumwandlungsausnahme fehl.ISortableList<T>
bieten, was noch nicht drin istIList<T>
? Oder anders gefragt, warum kann man nichtIList<T>
vor Ort sortieren, ohne die Elemente nach Ihrer imaginären statischen Methode erneut hinzuzufügen?IList<T>
Schnittstelle durchlaufen muss, um auf jedes Element zuzugreifen. Der Geschwindigkeitsunterschied ist so groß, dass es in vielen Fällen schneller sein kann, eine Liste in ein Array zu kopieren, das Array zu sortieren und die Liste zurück zu kopieren, als zu versuchen, die Liste von einer Sortierroutine verarbeiten zu lassen.ComparisonComparer
Klasse ist nicht notwendig. Sie könnenComparer<T>.Create(comparison)
stattdessen die statische Standardmethode verwenden.Du wirst so etwas tun müssen, denke ich (es in einen konkreteren Typ umwandeln).
Nehmen Sie es vielleicht in eine Liste von T und nicht in eine ArrayList, damit Sie Typensicherheit und mehr Optionen für die Implementierung des Vergleichers erhalten.
quelle
Die akzeptierte Antwort von @DavidMills ist ziemlich gut, aber ich denke, sie kann verbessert werden. Zum einen muss die
ComparisonComparer<T>
Klasse nicht definiert werden , wenn das Framework bereits eine statische Methode enthältComparer<T>.Create(Comparison<T>)
. Mit dieser Methode können Sie eine erstellenIComparison
on-the-fly .Außerdem wirft es,
IList<T>
fürIList
die das Potenzial besteht, gefährlich zu sein. In den meisten Fällen, die ich gesehen habe, wirdList<T>
das , was implementiertIList
wird, hinter den Kulissen verwendet, um zu implementierenIList<T>
, aber dies ist nicht garantiert und kann zu sprödem Code führen.Schließlich hat die überladene
List<T>.Sort()
Methode 4 Signaturen und nur 2 davon sind implementiert.List<T>.Sort()
List<T>.Sort(Comparison<T>)
List<T>.Sort(IComparer<T>)
List<T>.Sort(Int32, Int32, IComparer<T>)
Die folgende Klasse implementiert alle 4
List<T>.Sort()
Signaturen für dieIList<T>
Schnittstelle:Verwendung:
Hier geht es darum, die Funktionalität des Basiswerts
List<T>
zu nutzen, um die Sortierung nach Möglichkeit durchzuführen. Wiederum verwenden die meistenIList<T>
Implementierungen, die ich gesehen habe, dies. Wenn es sich bei der zugrunde liegenden Auflistung um einen anderen Typ handelt, greifen Sie auf das Erstellen einer neuen InstanzList<T>
mit Elementen aus der Eingabeliste zurück, verwenden Sie diese zum Sortieren und kopieren Sie die Ergebnisse zurück in die Eingabeliste. Dies funktioniert auch dann, wenn die Eingabeliste dieIList
Schnittstelle nicht implementiert .quelle
quelle
Ich habe diesen Thread gefunden, als ich nach einer Lösung für das genaue Problem gesucht habe, das im ursprünglichen Beitrag beschrieben wurde. Keine der Antworten entsprach jedoch vollständig meiner Situation. Brodys Antwort war ziemlich nah. Hier ist meine Situation und Lösung, die ich gefunden habe.
Ich habe zwei IListen desselben Typs, die von NHibernate zurückgegeben wurden, und habe die beiden IListen zu einer zusammengefasst, weshalb eine Sortierung erforderlich ist.
Wie Brody sagte, habe ich einen ICompare für das Objekt (ReportFormat) implementiert, der der Typ meiner IList ist:
Ich konvertiere dann die zusammengeführte IList in ein Array des gleichen Typs:
Sortieren Sie dann das Array:
Da ein eindimensionales Array die Schnittstelle implementiert
System.Collections.Generic.IList<T>
, kann das Array genau wie die ursprüngliche IList verwendet werden.quelle
Nützlich für die Rastersortierung. Diese Methode sortiert die Liste nach Eigenschaftsnamen. Wie folgt das Beispiel.
quelle
Hier ist ein Beispiel mit der stärkeren Eingabe. Ich bin mir nicht sicher, ob es unbedingt der beste Weg ist.
Die Cast-Funktion ist nur eine Neuimplementierung der Erweiterungsmethode, die mit 3.5 als normale statische Methode geschrieben wurde. Es ist leider ziemlich hässlich und wortreich.
quelle
Wenn ich in VS2008 auf die Dienstreferenz klicke und "Dienstreferenz konfigurieren" auswähle, kann optional festgelegt werden, wie der Client vom Dienst zurückgegebene Listen de-serialisiert.
Insbesondere kann ich zwischen System.Array, System.Collections.ArrayList und System.Collections.Generic.List wählen
quelle
Das ist hübsch! Ghetto.
quelle
Ich habe einen guten Beitrag dazu gefunden und dachte, ich würde ihn teilen. Schau es dir HIER an
Grundsätzlich.
Sie können die folgenden Klassen- und IComparer-Klassen erstellen
Wenn Sie eine IList haben, können Sie diese so sortieren.
Weitere Informationen finden Sie auf dieser Website. HIER
quelle
Ist das eine gültige Lösung?
Das Ergebnis war: IList B A C.
Liste A B C.
IList wieder A B C.
quelle
Das sieht viel einfacher aus, wenn Sie mich fragen. Das funktioniert perfekt für mich.
Sie können Cast () verwenden, um es in IList zu ändern, und dann OrderBy () verwenden:
WO T ist der Typ zB. Model.Employee oder Plugin.ContactService.Shared.Contact
Dann können Sie eine for-Schleife verwenden und fertig.
quelle
Konvertieren Sie Ihre Sammlung
IList
in eineList<T>
oder eine andere generische Sammlung, und Sie können sie dann einfach mithilfe desSystem.Linq
Namespace abfragen / sortieren (sie bietet eine Reihe von Erweiterungsmethoden).quelle
IList<T>
implementiertIEnumerable<T>
und muss daher nicht konvertiert werden, um Linq-Operationen zu verwenden.