Ich habe eine Klasse genannt , Order
die Eigenschaften wie hat OrderId
, OrderDate
, Quantity
, und Total
. Ich habe eine Liste dieser Order
Klasse:
List<Order> objListOrder = new List<Order>();
GetOrderList(objListOrder); // fill list of orders
Jetzt möchte ich die Liste basierend auf einer Eigenschaft des Order
Objekts sortieren, zum Beispiel muss ich sie nach dem Bestelldatum oder der Bestell-ID sortieren.
Wie kann ich das in C # machen?
Antworten:
Der einfachste Weg, den ich mir vorstellen kann, ist die Verwendung von Linq:
quelle
listWithObjects = listWithObjects.OrderByDescending(o => o.Status).ToList();
für ein solches Unterfangen ausreichen?Wenn Sie die Liste direkt sortieren müssen, können Sie die
Sort
Methode verwenden und einenComparison<T>
Delegaten übergeben:Wenn Sie lieber eine neue, sortierte Sequenz erstellen möchten, als direkt zu sortieren, können Sie die
OrderBy
in den anderen Antworten erwähnte Methode von LINQ verwenden .quelle
x
undy
auf der rechten Seite des Pfeils=>
.Nullable<>
(DateTime?
als Beispiel) können Sie verwenden,.Sort((x, y) => Nullable.Compare(x.OrderDate, y.OrderDate))
das null als vor allen Nicht-Null-Werten behandelt. Es ist genau das gleiche wie.Sort((x, y) => Comparer<DateTime?>.Default.Compare(x.OrderDate, y.OrderDate)
.Um dies ohne LINQ auf .Net2.0 zu tun:
Wenn Sie auf .Net3.0 sind, dann ist LukeH's Antwort , wonach Sie .
Um nach mehreren Eigenschaften zu sortieren, können Sie dies weiterhin innerhalb eines Delegaten tun. Zum Beispiel:
Dies würde Ihnen aufsteigende Daten mit absteigender Reihenfolge geben.
Ich würde jedoch nicht empfehlen, Delegierte zu halten, da dies viele Orte ohne Wiederverwendung von Code bedeutet. Sie sollten ein implementieren
IComparer
und dies einfach an IhreSort
Methode weitergeben. Siehe hier .Um diese IComparer-Klasse zu verwenden, instanziieren Sie sie einfach und übergeben Sie sie an Ihre Sortiermethode:
quelle
IComparer
Implementierungen haben zu können , die uns polymorphes Verhalten geben.Der einfachste Weg, eine Liste zu bestellen, ist die Verwendung
OrderBy
Wenn Sie nach mehreren Spalten sortieren möchten, z. B. nach folgender SQL-Abfrage.
Um dies zu erreichen, können Sie
ThenBy
Folgendes verwenden.quelle
Machen Sie es ohne Linq, wie Sie sagten:
Rufen Sie dann einfach .sort () in Ihrer Auftragsliste auf
quelle
null
auf dieas
Besetzung testen . Welches ist der springende Punktas
, da (ha, ha)(Order)obj
eine Ausnahme auslöst, wenn es fehlschlägt.if(orderToCompare == null) return 1;
.as
kehrt zurück,null
wenn die Besetzung fehlschlägt. Aber zumindest ist der Null-Test richtig.List<Order>
sodass der Typ garantiert mit dem übereinstimmt, in demas
Sie 2014 wahrscheinlich keinen Fehler geschrieben haben, und eine unnötige Schutzanweisung vermieden hat :)List<Order>
; Aber Sie und ich haben beide den selbst gekapselten Programmierer getroffen, dessen unausgesprochene Vermutung lautet: "Ich schreibe diesen Code, damit er nicht falsch verwendet wird"Eine klassische objektorientierte Lösung
Zuerst muss ich mich an die Großartigkeit von LINQ gewöhnen ... Jetzt, wo wir das aus dem Weg haben
Eine Variation der JimmyHoffa-Antwort. Mit Generika wird der
CompareTo
Parameter typsicher.Diese Standardsortierbarkeit kann natürlich wiederverwendet werden. Das heißt, jeder Client muss die Sortierlogik nicht redundant neu schreiben. Durch Vertauschen der "1" und "-1" (oder der Logikoperatoren Ihrer Wahl) wird die Sortierreihenfolge umgekehrt.
quelle
this
Objekt größer als null ist. Zum Sortieren ist eine Nullobjektreferenz "kleiner als"this
. Genau so habe ich beschlossen zu definieren, wie Nullen sortiert werden.// Völlig generische Sortierung zur Verwendung mit einer Rasteransicht
quelle
data.OrderBy()
. Etwas einfacher als das Rad neu zu erfinden.Hier ist eine generische LINQ-Erweiterungsmethode, mit der keine zusätzliche Kopie der Liste erstellt wird:
Um es zu benutzen:
Ich habe kürzlich dieses zusätzliche erstellt, das ein akzeptiert
ICompare<U>
, damit Sie den Vergleich anpassen können. Dies war praktisch, als ich eine natürliche String-Sortierung durchführen musste:quelle
OrderBy
macht das alles intern.void
Erweiterungsmethode in diesem Sinne zu schreiben :static class Extensions { public static void SortBy<TSource, TKey>(this List<TSource> self, Func<TSource, TKey> keySelector) { self.SortBy(keySelector, Comparer<TKey>.Default); } public static void SortBy<TSource, TKey>(this List<TSource> self, Func<TSource, TKey> keySelector, IComparer<TKey> comparer) { self.Sort((x, y) => comparer.Compare(keySelector(x), keySelector(y))); } }
Kann durch eineSortByDescending
Methode ergänzt werden . @ Servys Kommentare gelten auch für meinen Code!Verwenden von LINQ
quelle
quelle
Eine verbesserte Version von Roger.
Das Problem mit GetDynamicSortProperty ist, dass nur die Eigenschaftsnamen abgerufen werden. Was passiert jedoch, wenn wir in der GridView NavigationProperties verwenden? Es wird eine Ausnahme gesendet, da null gefunden wird.
Beispiel:
"Employee.Company.Name;" stürzt ab ... da nur "Name" als Parameter seinen Wert abrufen kann.
Hier ist eine verbesserte Version, mit der wir nach Navigationseigenschaften sortieren können.
quelle
Sie können etwas allgemeineres an der Eigenschaftenauswahl vornehmen, jedoch den Typ, aus dem Sie auswählen, genau angeben, in Ihrem Fall 'Bestellung':
Schreiben Sie Ihre Funktion als generische:
und dann benutze es so:
Sie können noch allgemeiner sein und einen offenen Typ für das definieren, was Sie bestellen möchten:
und benutze es genauso:
Das ist eine blöde, unnötig komplexe Art, einen LINQ-Stil 'OrderBy' zu erstellen, aber es kann Ihnen einen Hinweis darauf geben, wie er generisch implementiert werden kann
quelle
Bitte lassen Sie mich die Antwort von @LukeH mit einem Beispielcode vervollständigen, da ich ihn getestet habe. Ich glaube, dass er für einige nützlich sein kann:
quelle
quelle
Nutzen Sie LiNQ
OrderBy
quelle
Basierend auf dem GenericTypeTea -Vergleicher:
Durch Hinzufügen von Sortierflags können wir mehr Flexibilität erzielen :
In diesem Szenario müssen Sie es explizit als MyOrderingClass (und nicht als IComparer ) instanziieren
, um seine Sortiereigenschaften festzulegen :
quelle
Keine der obigen Antworten war allgemein genug für mich, also habe ich diese gemacht:
Vorsicht bei großen Datenmengen. Es ist ein einfacher Code, der Sie jedoch in Schwierigkeiten bringen kann, wenn die Sammlung sehr groß ist und der Objekttyp der Sammlung eine große Anzahl von Feldern enthält. Die Laufzeit ist NxM, wobei:
N = Anzahl der Elemente in der Sammlung
M = Anzahl der Eigenschaften innerhalb des Objekts
quelle
Jeder, der mit nullbaren Typen arbeitet,
Value
muss diese verwendenCompareTo
.objListOrder.Sort((x, y) => x.YourNullableType.Value.CompareTo(y.YourNullableType.Value));
quelle
Aus Sicht der Leistung ist es am besten, eine sortierte Liste zu verwenden, damit die Daten beim Hinzufügen zum Ergebnis sortiert werden. Andere Ansätze erfordern mindestens eine zusätzliche Iteration der Daten und die meisten erstellen eine Kopie der Daten, sodass nicht nur die Leistung, sondern auch die Speichernutzung beeinträchtigt wird. Möglicherweise handelt es sich nicht um ein Problem mit einigen Hundert Elementen, sondern um Tausende, insbesondere bei Diensten, bei denen viele gleichzeitige Anforderungen möglicherweise gleichzeitig sortiert werden. Schauen Sie sich den System.Collections.Generic-Namespace an und wählen Sie eine Klasse mit Sortierung anstelle von List.
Vermeiden Sie nach Möglichkeit generische Implementierungen mit Reflection. Dies kann ebenfalls zu Leistungsproblemen führen.
quelle
Angenommen, Sie haben den folgenden Code. In diesem Code haben wir eine Passenger-Klasse mit einigen Eigenschaften, nach denen wir sortieren möchten.
So können Sie Ihre Sortierstruktur mithilfe des Kompositionsdelegaten implementieren.
quelle