So sortieren Sie eine Liste <T> nach einer Eigenschaft im Objekt

1248

Ich habe eine Klasse genannt , Orderdie Eigenschaften wie hat OrderId, OrderDate, Quantity, und Total. Ich habe eine Liste dieser OrderKlasse:

List<Order> objListOrder = new List<Order>();
GetOrderList(objListOrder); // fill list of orders

Jetzt möchte ich die Liste basierend auf einer Eigenschaft des OrderObjekts sortieren, zum Beispiel muss ich sie nach dem Bestelldatum oder der Bestell-ID sortieren.

Wie kann ich das in C # machen?

Shyju
quelle
9
Warten Sie - Sie sowohl Bestelldatum sortiert werden soll und Auftrags - ID? Weil die meisten Antworten davon ausgehen, dass Sie nur nach dem einen oder anderen sortieren.
GalacticCowboy
@GalacticCowboy, @GenericTypeTea: Die Frage lautet "Ich möchte die Liste nach einer Eigenschaft des Order-Objekts sortieren ", aber ich stimme zu, dass es an anderer Stelle nicht ganz klar ist. In beiden Fällen spielt es keine große Rolle, ob Sie nach einer oder mehreren Eigenschaften sortieren müssen.
LukeH
@ LukeH - Hatte gerade eine vierte Wiederholung und ich stimme zu. 'Ich möchte die Liste nach einer Eigenschaft sortieren' ... und 'Bestelldatum oder Bestellnummer'. Zwischen all den Antworten haben wir alle Grundlagen abgedeckt :).
djdd87

Antworten:

1807

Der einfachste Weg, den ich mir vorstellen kann, ist die Verwendung von Linq:

List<Order> SortedList = objListOrder.OrderBy(o=>o.OrderDate).ToList();
Lazarus
quelle
22
Wie kann ich das in absteigender Reihenfolge sortieren?
Netter Bär
229
@BonusKun List <Order> SortedList = objListOrder. OrderByDescending (o => o.OrderDate) .ToList ();
Javajavajavajavajava
77
Beachten Sie, dass dadurch eine völlig neue Liste mit allen Elementen im Speicher erstellt wird, was hinsichtlich der Leistung problematisch sein kann .
Staafl
14
@staafl wird listWithObjects = listWithObjects.OrderByDescending(o => o.Status).ToList();für ein solches Unterfangen ausreichen?
Andrew Grinder
28
@staafl Wir bestellen eine Liste von Objektreferenzen und duplizieren die Objekte meines Wissens nicht selbst. Dies verdoppelt zwar den von der Referenzliste verwendeten Speicher, ist jedoch nicht so schlimm wie das tatsächliche Duplizieren aller Objekte selbst. In den meisten Szenarien außerhalb derjenigen, in denen es sich um große Datenmengen handelt und diese im Speicher zu halten, ist dies bereits ein Problem es sollte ausreichen.
Lazarus
798

Wenn Sie die Liste direkt sortieren müssen, können Sie die SortMethode verwenden und einen Comparison<T>Delegaten übergeben:

objListOrder.Sort((x, y) => x.OrderDate.CompareTo(y.OrderDate));

Wenn Sie lieber eine neue, sortierte Sequenz erstellen möchten, als direkt zu sortieren, können Sie die OrderByin den anderen Antworten erwähnte Methode von LINQ verwenden .

LukeH
quelle
30
Ja, dies ist die "richtige" Antwort und sollte viel effizienter sein, als eine neue IEnumerable zu erstellen und sie dann in eine neue Liste zu konvertieren.
Jonathan Wood
45
Natürlich, wenn Sie brauchen absteigend sortieren, tauschen xund yauf der rechten Seite des Pfeils =>.
Jeppe Stig Nielsen
15
Die eigentliche Antwort, die die Liste tatsächlich sortiert
Mitchell Currie
3
@PimBrouwers Dies ist der bessere Optionszeitraum. Auch wenn die von Ihnen verwendete Speichermenge kein Problem darstellt, vermeidet diese Lösung eine unnötige Speicherzuweisung, die EXTREM teuer ist. Diese Option ist genauso einfach codeweise und eine Größenordnung schneller.
Cdaragorn
12
@JonSchneider Für 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).
Jeppe Stig Nielsen
219

Um dies ohne LINQ auf .Net2.0 zu tun:

List<Order> objListOrder = GetOrderList();
objListOrder.Sort(
    delegate(Order p1, Order p2)
    {
        return p1.OrderDate.CompareTo(p2.OrderDate);
    }
);

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:

orderList.Sort(
    delegate(Order p1, Order p2)
    {
        int compareDate = p1.Date.CompareTo(p2.Date);
        if (compareDate == 0)
        {
            return p2.OrderID.CompareTo(p1.OrderID);
        }
        return compareDate;
    }
);

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 IComparerund dies einfach an Ihre SortMethode weitergeben. Siehe hier .

public class MyOrderingClass : IComparer<Order>
{
    public int Compare(Order x, Order y)
    {
        int compareDate = x.Date.CompareTo(y.Date);
        if (compareDate == 0)
        {
            return x.OrderID.CompareTo(y.OrderID);
        }
        return compareDate;
    }
}

Um diese IComparer-Klasse zu verwenden, instanziieren Sie sie einfach und übergeben Sie sie an Ihre Sortiermethode:

IComparer<Order> comparer = new MyOrderingClass();
orderList.Sort(comparer);
djdd87
quelle
1
Hervorragende Antwort und sollte die richtige sein, da sie die Neuinitialisierung der ursprünglichen Liste (was die LINQ-Version immer tut) schützt und eine bessere Kapselung bietet.
Jeb
@wonton, nein. Die Idee ist, verschiedene IComparerImplementierungen haben zu können , die uns polymorphes Verhalten geben.
Radarbob
Hat für mich gearbeitet. Ich habe eine Version davon mit Sortieroptionen veröffentlicht.
Jack Griffin
109

Der einfachste Weg, eine Liste zu bestellen, ist die Verwendung OrderBy

 List<Order> objListOrder = 
    source.OrderBy(order => order.OrderDate).ToList();

Wenn Sie nach mehreren Spalten sortieren möchten, z. B. nach folgender SQL-Abfrage.

ORDER BY OrderDate, OrderId

Um dies zu erreichen, können Sie ThenByFolgendes verwenden.

  List<Order> objListOrder = 
    source.OrderBy(order => order.OrderDate).ThenBy(order => order.OrderId).ToList();
PSK
quelle
32

Machen Sie es ohne Linq, wie Sie sagten:

public class Order : IComparable
{
    public DateTime OrderDate { get; set; }
    public int OrderId { get; set; }

    public int CompareTo(object obj)
    {
        Order orderToCompare = obj as Order;
        if (orderToCompare.OrderDate < OrderDate || orderToCompare.OrderId < OrderId)
        {
            return 1;
        }
        if (orderToCompare.OrderDate > OrderDate || orderToCompare.OrderId > OrderId)
        {
            return -1;
        }

        // The orders are equivalent.
        return 0;
    }
}

Rufen Sie dann einfach .sort () in Ihrer Auftragsliste auf

Jimmy Hoffa
quelle
3
Man muss zuerst nullauf die asBesetzung testen . Welches ist der springende Punkt as, da (ha, ha) (Order)objeine Ausnahme auslöst, wenn es fehlschlägt. if(orderToCompare == null) return 1;.
Radarbob
+1 für die Verwendung der Schnittstelle, wodurch der Code einfacher zu warten ist und die Funktionen des Objekts deutlich sichtbar werden.
AeonOfTime
Wenn Bill und Ted jemals auftauchen, werde ich sie bitten, mich zum 16. Oktober 2014 zurückzubringen, damit ich meinen Fehler oben korrigieren kann - askehrt zurück, nullwenn die Besetzung fehlschlägt. Aber zumindest ist der Null-Test richtig.
Radarbob
@ Radarbob ja .. oops. :) Aber! Diese Funktion soll automatisch von einer Sortierung über eine Liste verwendet werden, List<Order>sodass der Typ garantiert mit dem übereinstimmt, in dem asSie 2014 wahrscheinlich keinen Fehler geschrieben haben, und eine unnötige Schutzanweisung vermieden hat :)
Jimmy Hoffa
sollte garantiert werden Interessanter Punkt. Wenn es so gut gekapselt ist, dass es nur aufgerufen werden kann, um a zu übergeben 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"
Radarbob
26

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 CompareToParameter typsicher.

public class Order : IComparable<Order> {

    public int CompareTo( Order that ) {
        if ( that == null ) return 1;
        if ( this.OrderDate > that.OrderDate) return 1;
        if ( this.OrderDate < that.OrderDate) return -1;
        return 0;
    }
}

// in the client code
// assume myOrders is a populated List<Order>
myOrders.Sort(); 

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.

Radarbob
quelle
Einfacher Ansatz zum Sortieren von Objekten in einer Liste. Aber ich verstehe nicht, warum Sie 1 zurückgeben, wenn (das == null)?
Loc Huynh
4
Dies bedeutet, dass das thisObjekt größer als null ist. Zum Sortieren ist eine Nullobjektreferenz "kleiner als" this. Genau so habe ich beschlossen zu definieren, wie Nullen sortiert werden.
Radarbob
18

// Völlig generische Sortierung zur Verwendung mit einer Rasteransicht

public List<T> Sort_List<T>(string sortDirection, string sortExpression, List<T> data)
    {

        List<T> data_sorted = new List<T>();

        if (sortDirection == "Ascending")
        {
            data_sorted = (from n in data
                              orderby GetDynamicSortProperty(n, sortExpression) ascending
                              select n).ToList();
        }
        else if (sortDirection == "Descending")
        {
            data_sorted = (from n in data
                              orderby GetDynamicSortProperty(n, sortExpression) descending
                              select n).ToList();

        }

        return data_sorted;

    }

    public object GetDynamicSortProperty(object item, string propName)
    {
        //Use reflection to get order type
        return item.GetType().GetProperty(propName).GetValue(item, null);
    }
Roger
quelle
4
Oder wissen Sie , data.OrderBy(). Etwas einfacher als das Rad neu zu erfinden.
gunr2171
4
Die Idee ist, dass dies mit jedem Objekttyp funktioniert. Wobei als OrderBy () nur mit stark typisierten Objekten funktioniert.
Roger
1
Vielen Dank. Meiner Meinung nach die einfachste und benutzerfreundlichste Lösung zum Sortieren von Rasterdaten!
kostas ch.
6

Hier ist eine generische LINQ-Erweiterungsmethode, mit der keine zusätzliche Kopie der Liste erstellt wird:

public static void Sort<T,U>(this List<T> list, Func<T, U> expression)
    where U : IComparable<U>
{
    list.Sort((x, y) => expression.Invoke(x).CompareTo(expression.Invoke(y)));
}

Um es zu benutzen:

myList.Sort(x=> x.myProperty);

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:

public static void Sort<T, U>(this List<T> list, Func<T, U> expression, IComparer<U> comparer)
    where U : IComparable<U>
{    
    list.Sort((x, y) => comparer.Compare(expression.Invoke(x), expression.Invoke(y)));
}
Peter
quelle
Ich habe das implementiert, funktioniert gut. Ich habe einen "isAscending = true" -Parameter hinzugefügt. Um in absteigender Reihenfolge zu sortieren, tauschen Sie einfach x und y innerhalb der beiden Invoke () -Methoden aus. Vielen Dank.
Rob L
Wenn Sie nur den Ausdruck kompilieren möchten, können Sie auch zunächst einen Delegaten akzeptieren. Darüber hinaus weist dieser Ansatz große Probleme auf, wenn der Selektor Nebenwirkungen verursacht, teuer in der Berechnung ist oder nicht deterministisch ist. Eine ordnungsgemäße Sortierung basierend auf einem ausgewählten Ausdruck muss den Selektor nicht mehr als einmal pro Element in der Liste aufrufen.
Servy
@Servy - das sind alles gültige Punkte, aber ich bin ehrlich, ich bin mir nicht sicher, wie ich einige Ihrer Vorschläge umsetzen soll (insbesondere, um zu verhindern, dass ein Selektor Nebenwirkungen verursacht ...?). Ich habe sie in Delegierte geändert. Wenn Sie wissen, wie Sie einige dieser Änderungen vornehmen können, würde ich mich freuen, wenn Sie meinen Code bearbeiten.
Peter
3
@Peter Sie können nicht verhindern, dass die Delegierten Nebenwirkungen verursachen. Was Sie tun können , ist sicherzustellen , dass sie sind nie mehr als einmal pro Objekt aufgerufen, das bedeutet , die Werte für jedes Objekt der Berechnung, Speicherung der Objekt / projiziert-Wert - Paare und Sortieren dann , dass . OrderBymacht das alles intern.
Servy
Eine weitere gute Möglichkeit, eine voidErweiterungsmethode 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 eine SortByDescendingMethode ergänzt werden . @ Servys Kommentare gelten auch für meinen Code!
Jeppe Stig Nielsen
4

Verwenden von LINQ

objListOrder = GetOrderList()
                   .OrderBy(o => o.OrderDate)
                   .ToList();

objListOrder = GetOrderList()
                   .OrderBy(o => o.OrderId)
                   .ToList();
Daniel A. White
quelle
3
//Get data from database, then sort list by staff name:

List<StaffMember> staffList = staffHandler.GetStaffMembers();

var sortedList = from staffmember in staffList
                 orderby staffmember.Name ascending
                 select staffmember;
Waqas Ahmed
quelle
3

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.

public object GetDynamicSortProperty(object item, string propName)
    {
        try
        {                 
            string[] prop = propName.Split('.'); 

            //Use reflection to get order type                   
            int i = 0;                    
            while (i < prop.Count())
            {
                item = item.GetType().GetProperty(prop[i]).GetValue(item, null);
                i++;
            }                     

            return item;
        }
        catch (Exception ex)
        {
            throw ex;
        }


    } 
Miguel Becerra
quelle
3

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:

public List<Order> GetOrderList<T>(IEnumerable<Order> orders, Func<Order, T> propertySelector)
        {
            return (from order in orders
                    orderby propertySelector(order)
                    select order).ToList();
        } 

und dann benutze es so:

var ordersOrderedByDate = GetOrderList(orders, x => x.OrderDate);

Sie können noch allgemeiner sein und einen offenen Typ für das definieren, was Sie bestellen möchten:

public List<T> OrderBy<T,P>(IEnumerable<T> collection, Func<T,P> propertySelector)
        {
            return (from item in collection
                    orderby propertySelector(item)
                    select item).ToList();
        } 

und benutze es genauso:

var ordersOrderedByDate = OrderBy(orders, x => x.OrderDate);

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

Danny Mor
quelle
3

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:

public class Order
{
    public string OrderId { get; set; }
    public DateTime OrderDate { get; set; }
    public int Quantity { get; set; }
    public int Total { get; set; }

    public Order(string orderId, DateTime orderDate, int quantity, int total)
    {
        OrderId = orderId;
        OrderDate = orderDate;
        Quantity = quantity;
        Total = total;
    }
}

public void SampleDataAndTest()
{
    List<Order> objListOrder = new List<Order>();

    objListOrder.Add(new Order("tu me paulo ", Convert.ToDateTime("01/06/2016"), 1, 44));
    objListOrder.Add(new Order("ante laudabas", Convert.ToDateTime("02/05/2016"), 2, 55));
    objListOrder.Add(new Order("ad ordinem ", Convert.ToDateTime("03/04/2016"), 5, 66));
    objListOrder.Add(new Order("collocationem ", Convert.ToDateTime("04/03/2016"), 9, 77));
    objListOrder.Add(new Order("que rerum ac ", Convert.ToDateTime("05/02/2016"), 10, 65));
    objListOrder.Add(new Order("locorum ; cuius", Convert.ToDateTime("06/01/2016"), 1, 343));


    Console.WriteLine("Sort the list by date ascending:");
    objListOrder.Sort((x, y) => x.OrderDate.CompareTo(y.OrderDate));

    foreach (Order o in objListOrder)
        Console.WriteLine("OrderId = " + o.OrderId + " OrderDate = " + o.OrderDate.ToString() + " Quantity = " + o.Quantity + " Total = " + o.Total);

    Console.WriteLine("Sort the list by date descending:");
    objListOrder.Sort((x, y) => y.OrderDate.CompareTo(x.OrderDate));
    foreach (Order o in objListOrder)
        Console.WriteLine("OrderId = " + o.OrderId + " OrderDate = " + o.OrderDate.ToString() + " Quantity = " + o.Quantity + " Total = " + o.Total);

    Console.WriteLine("Sort the list by OrderId ascending:");
    objListOrder.Sort((x, y) => x.OrderId.CompareTo(y.OrderId));
    foreach (Order o in objListOrder)
        Console.WriteLine("OrderId = " + o.OrderId + " OrderDate = " + o.OrderDate.ToString() + " Quantity = " + o.Quantity + " Total = " + o.Total);

    //etc ...
}
Molbalga
quelle
3
var obj = db.Items.Where...

var orderBYItemId = obj.OrderByDescending(c => Convert.ToInt32(c.ID));
Jevgenij Kononov
quelle
1

Nutzen Sie LiNQ OrderBy

List<Order> objListOrder=new List<Order> ();
    objListOrder=GetOrderList().OrderBy(o=>o.orderid).ToList();
Pranay Rana
quelle
1

Basierend auf dem GenericTypeTea -Vergleicher:
Durch Hinzufügen von Sortierflags können wir mehr Flexibilität erzielen :

public class MyOrderingClass : IComparer<Order> {  
    public int Compare(Order x, Order y) {  
        int compareDate = x.Date.CompareTo(y.Date);  
        if (compareDate == 0) {  
            int compareOrderId = x.OrderID.CompareTo(y.OrderID);  

            if (OrderIdDescending) {  
                compareOrderId = -compareOrderId;  
            }  
            return compareOrderId;  
        }  

        if (DateDescending) {  
            compareDate = -compareDate;  
        }  
        return compareDate;  
    }  

    public bool DateDescending { get; set; }  
    public bool OrderIdDescending { get; set; }  
}  

In diesem Szenario müssen Sie es explizit als MyOrderingClass (und nicht als IComparer ) instanziieren
, um seine Sortiereigenschaften festzulegen :

MyOrderingClass comparer = new MyOrderingClass();  
comparer.DateDescending = ...;  
comparer.OrderIdDescending = ...;  
orderList.Sort(comparer);  
Jack Griffin
quelle
1

Keine der obigen Antworten war allgemein genug für mich, also habe ich diese gemacht:

var someUserInputStringValue = "propertyNameOfObject i.e. 'Quantity' or 'Date'";
var SortedData = DataToBeSorted
                   .OrderBy(m => m.GetType()
                                  .GetProperties()
                                  .First(n => 
                                      n.Name == someUserInputStringValue)
                   .GetValue(m, null))
                 .ToList();

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

itcropper
quelle
1

Jeder, der mit nullbaren Typen arbeitet, Valuemuss diese verwenden CompareTo.

objListOrder.Sort((x, y) => x.YourNullableType.Value.CompareTo(y.YourNullableType.Value));

Jude
quelle
0

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.

user3285954
quelle
Wie kann dies performanter sein? Das Einfügen von Daten in eine sortierte Liste ist O (n), das Hinzufügen von n Elementen ist also O (n ^ 2). Was versuchen viele gleichzeitige Elemente hinzuzufügen? Es gibt Situationen, in denen Sie zusätzliche CPU-Zyklen brennen müssen, während Elemente hinzugefügt werden. Dies ist jedoch keine gute allgemeine Lösung.
John La Rooy
0

Angenommen, Sie haben den folgenden Code. In diesem Code haben wir eine Passenger-Klasse mit einigen Eigenschaften, nach denen wir sortieren möchten.

public class Passenger
{
    public string Name { get; }
    public string LastName { get; }
    public string PassportNo { get; }
    public string Nationality { get; }

    public Passenger(string name, string lastName, string passportNo, string nationality)
    {
        this.Name = name;
        this.LastName = lastName;
        this.PassportNo = passportNo;
        this.Nationality = nationality;
    }

    public static int CompareByName(Passenger passenger1, Passenger passenger2)
    {
        return String.Compare(passenger1.Name, passenger2.Name);
    }

    public static int CompareByLastName(Passenger passenger1, Passenger passenger2)
    {
        return String.Compare(passenger1.LastName, passenger2.LastName);
    }

    public static int CompareNationality(Passenger passenger1, Passenger passenger2)
    {
        return String.Compare(passenger1.Nationality, passenger2.Nationality);
    }
}

public class TestPassengerSort
{
    Passenger p1 = new Passenger("Johon", "Floid", "A123456789", "USA");
    Passenger p2 = new Passenger("Jo", "Sina", "A987463215", "UAE");
    Passenger p3 = new Passenger("Ped", "Zoola", "A987855215", "Italy");

    public void SortThem()
    {
        Passenger[] passengers = new Passenger[] { p1, p2, p3 };
        List<Passenger> passengerList = new List<Passenger> { p1, p2, p3 };

        Array.Sort(passengers, Passenger.CompareByName);
        Array.Sort(passengers, Passenger.CompareByLastName);
        Array.Sort(passengers, Passenger.CompareNationality);

        passengerList.Sort(Passenger.CompareByName);
        passengerList.Sort(Passenger.CompareByLastName);
        passengerList.Sort(Passenger.CompareNationality);

    }
}

So können Sie Ihre Sortierstruktur mithilfe des Kompositionsdelegaten implementieren.

Seyedraouf Modarresi
quelle