TOC

This article has been localized into German by the community.

Sammlungen:

Listen

C # hat eine Reihe von Klassen für den Umgang mit Listen. Sie implementieren die "IList" -Schnittstelle und die am weitesten verbreitete Implementierung ist die generische Liste, die oft als List<T> bezeichnet wird. Das T gibt den Typ der Objekte an, die in der Liste enthalten sind, was den zusätzlichen Vorteil hat, dass der Compiler prüft, ob nur Objekte der richtigen Art zur Liste hinzugefügt werden - mit anderen Worten, die List<T> ist typsicher.

List oder "Liste T" ähnelt der "ArrayList" -Klasse, bei der es sich um die Auswahlliste für generische Listen von C# handelt bevor diese unterstützt wurden. Daher werden Sie auch sehen, dass die List gleich viel von dem gleichen Zeug kann wie ein Array (das übrigens auch die "IList" -Schnittstelle implementiert), aber in vielen Situationen ist es leichter und einfacher mit List zu arbeiten. Sie müssen zum Beispiel keine Liste mit einer bestimmten Größe erstellen, sondern können sie einfach erstellen und .NET wird automatisch so erweitert, dass sie der Anzahl der Elemente entspricht, die Sie hinzufügen.

Wie bereits erwähnt, steht T für den Typ und wird verwendet, um den Typ der Objekte anzugeben, die die Liste enthalten soll. In unserem ersten Beispiel zeige ich Ihnen, wie Sie eine Liste erstellen, die Strings enthalten sollte:

List<string> listOfStrings = new List<string>();

Dies erzeugt eine leere Liste, aber mit der Add -Methode ist es sehr einfach, Sachen hinzuzufügen:

listOfStrings.Add("a string");

Wenn Sie jedoch versuchen, etwas hinzuzufügen, das keine Zeichenfolge ist, wird der Compiler sofort darüber beschweren:

listOfStrings.Add(2);
Error   CS1503  Argument 1: cannot convert from 'int' to 'string'

Initialisierung einer Liste mit Elementen

Im obigen Beispiel haben wir gerade eine Liste erstellt und dann ein Element hinzugefügt. Mit C# können Sie jedoch tatsächlich eine Liste erstellen UND innerhalb derselben Anweisung Elemente hinzufügen, indem Sie eine Technik namens Sammlungsinitialisierer verwenden. Mal sehen, wie es gemacht wird:

List<string> listOfNames = new List<string>()
{
    "John Doe",
    "Jane Doe",
    "Joe Doe"
};

Die Syntax ist ziemlich einfach: Vor dem üblichen Endsemikolon haben wir eine Reihe geschweifter Klammern, die wiederum eine Liste der Werte enthält, die wir von Anfang an in der Liste haben wollen. Da es sich um eine Liste von Strings handelt, sollten die von uns bereitgestellten Ausgangsobjekte natürlich vom Stringtyp sein. Das Gleiche kann jedoch für eine Liste anderer Typen erreicht werden, selbst wenn wir unsere eigenen Klassen verwenden, wie ich im nächsten Beispiel demonstrieren werde.

Arbeiten mit Elementen

Es gibt mehrere Möglichkeiten, mit den Elementen einer generischen Liste zu arbeiten, und um einige davon zu zeigen, habe ich ein größeres Beispiel erstellt:

using System;
using System.Collections.Generic;

namespace Lists
{
    class Program
    {
static void Main(string[] args)
{
    List<User> listOfUsers = new List<User>()
    {
new User() { Name = "John Doe", Age = 42 },
new User() { Name = "Jane Doe", Age = 34 },
new User() { Name = "Joe Doe", Age = 8 },
    };

    for(int i = 0; i < listOfUsers.Count; i++)
    {
Console.WriteLine(listOfUsers[i].Name + " is " + listOfUsers[i].Age + " years old");
    }
    Console.ReadKey();
}
    }

    class User
    {
public string Name { get; set; }

public int Age { get; set; }
    }
}

Fangen wir von unten an, wo wir eine einfache Klasse für Informationen über einen Benutzer definieren - nur einen Namen und ein Alter. Zurück zum oberen Teil des Beispiels, wo ich unsere Liste geändert habe, um diese Benutzerklasse anstelle einfacher Zeichenfolgen zu verwenden. Ich verwende einen Auflistungsinitialisierer, um die Liste mit Benutzern aufzufüllen - beachten Sie, dass die Syntax die gleiche wie zuvor ist, nur ein bisschen komplexer, weil wir es mit einem komplexeren Objekt als einem String zu tun haben.

Sobald wir die Liste fertig haben, benutze ich eine for -Schleife - um zu wissen, wie viele Iterationen wir machen werden, verwende ich die Eigenschaft Count von Liste. Bei jeder Iteration greife ich über den Indexer der Liste auf den betreffenden Benutzer zu, wobei die Syntax der eckigen Klammer verwendet wird (z. B. listOfUsers[i]). Sobald ich den Benutzer habe, gebe ich Name und Alter aus.

Hinzufügen, Einfügen & Löschen von Elementen

Wir haben bereits versucht, einen einzelnen Eintrag zu einer Liste hinzuzufügen, aber es gibt mehrere Möglichkeiten, dies zu tun. Zuallererst können Sie ein Element einfügen, anstatt es hinzuzufügen. Der Unterschied besteht darin, dass die Methode Add immer am Ende der Liste hinzugefügt wird, die Insert -Methode jedoch erlaubt einen Artikel an einer bestimmten Position einfügen. Hier ist ein Beispiel:

List<string> listOfNames = new List<string>()
{
    "Joe Doe"
};
// Insert at the top (index 0)
listOfNames.Insert(0, "John Doe");
// Insert in the middle (index 1)
listOfNames.Insert(1, "Jane Doe");

Wir beginnen die Liste mit nur einem Element, fügen dann aber zwei weitere Elemente ein, zuerst oben in der Liste und dann in der Mitte. Der erste Parameter der Insert-Methode ist der Index, in den das Element eingefügt werden soll. Seien Sie jedoch vorsichtig - eine Ausnahme wird ausgelöst, wenn Sie versuchen, ein Objekt in Index 3 einzufügen, wenn die Liste weniger Elemente enthält!

Hinzufügen mehrerer Elemente

Genau wie wir die Methoden Hinzufügen und Einfügen zum Hinzufügen eines einzelnen Elements haben, gibt es auch entsprechende Methoden zum Hinzufügen und Einfügen mehrerer Elemente. Sie heißen AddRange() und InsertRange() und akzeptieren jede Art von Sammlung, die das aufzählen der Schnittstelle als Parameter berücksichtigt - dies könnte z.B.: ein Array von Elementen oder eine andere Liste sein, welchem Sie Elemente hinzufügen oder in die aktuelle Liste einfügen möchten.

Als Beispiel für die "Range"-Methoden machen wir etwas lustiges - wir kombinieren die "AddRange"-Methode mit einem Auflistungsinitialisierer, um einer vorhandenen Liste in einer einzelnen Anweisung mehrere neue Namen hinzuzufügen:

listOfNames.AddRange(new string[]
    {
"Jenna Doe",
"Another Doe"
    });

Wir erstellen einfach ein Array von Strings im Handumdrehen und fügen seine Elemente sofort an unsere Liste von Namen aus dem vorherigen Beispiel an.

Entfernen von Elementen

Ihnen stehen derzeit drei Methoden zur Verfügung, wenn Sie ein oder mehrere Elemente aus einer Liste entfernen möchten: Remove(), RemoveAt() und RemoveAll().

Die Methode Remove() benötigt nur einen Parameter: Das Objekt, das Sie entfernen möchten. Dies ist z.B. eine Liste von Strings oder Ganzzahlen, weil Sie einfach das Element schreiben können, das Sie entfernen möchten. Andererseits, wenn Sie eine Liste komplexer Objekte haben, müssten Sie dieses Objekt zuerst finden, um einen Verweis zu erhalten, den Sie an die Remove() -Methode übergeben könnten. Lassen Sie uns das später behandeln - hier ist ein sehr einfaches Beispiel wie Sie ein einzelnes Element mit der Remove() -Methode entfernen können:

List<string> listOfNames = new List<string>()
{
    "John Doe",
    "Jane Doe",
    "Joe Doe",
    "Another Doe"
};

listOfNames.Remove("Joe Doe");

Die Remove() -Methode durchsucht einfach die Liste, bis sie die erste Instanz des Objekts findet, das Sie zum Entfernen angegeben haben, und sie entfernt sie - sie entfernt nur eine Instanz und wenn Sie ein Element in der Liste angeben, das nicht existiert, wird kein Fehler ausgegeben. Die Methode gibt true zurück, wenn sie ein Element entfernen konnte, und false, wenn dies nicht der Fall war.

Die RemoveAt() -Methode nutzt die Tatsache, dass die generische Liste indexbasiert ist, indem Sie ein Element basierend auf seinem Index / seiner Position in der Liste entfernen können. Zum Beispiel könnten Sie das erste Element wie folgt aus der Liste entfernen:

listOfNames.RemoveAt(0);

Oder das letzte Element in der Liste wie folgt:

listOfNames.RemoveAt(listOfNames.Count - 1);

Auch hier wird nur ein einzelnes Objekt entfernt, und dieses Mal sollten Sie vorsichtig sein, wenn Sie den Index des zu entfernenden Objekts angeben - wenn Sie einen Index verwenden, der außerhalb des zulässigen Bereichs liegt (niedriger als 0 oder höher als die Anzahl der Elemente) wird eine Ausnahme geworfen! Wenn Sie also nicht sicher sind, was Sie tun, sollten Sie die RemoveAt() -Methode in einen try-catch-Block für die Behandlung der Ausnahme einbinden (an anderer Stelle in diesem Tutorial ausführlich erläutert). Die RemoveAt() -Methode gibt nichts zurück, daher müssen Sie die Anzahl der Elemente in der Liste vor und nach dem Aufruf prüfen, um zu entscheiden, ob sie erfolgreich war - auf der anderen Seite, wenn Sie wissen, dass Sie einen Index haben der in der Liste vorhanden ist, was Sie immer sicherstellen sollten, dann können Sie immer erwarten, dass RemoveAt() erfolgreich ist.

Die RemoveAll() ist die komplexeste der remove-Methoden, aber definitiv auch die mächtigste. Sie nimmt einen Delegaten als Parameter zu einer Methode, und diese Methode entscheidet dann, ob ein Element entfernt werden soll oder nicht, indem Wahr oder Falsch zurückgegeben wird. Auf diese Weise können Sie beim Entfernen von Objekten Ihre eigene Logik anwenden. Außerdem können Sie mehrere Elemente gleichzeitig entfernen. Delegierte werden an anderer Stelle in diesem Lernprogramm behandelt, da es sich um ein großes und komplexes Thema handelt. Ich möchte jedoch, dass Sie sich ein Bild davon machen, wie cool die RemoveAll-Methode ist. Hier ein Beispiel:

List<string> listOfNames = new List<string>()
{
    "John Doe",
    "Jane Doe",
    "Joe Doe",
    "Another Doe"
};

listOfNames.RemoveAll(name =>
{
    if (name.StartsWith("J"))
return true;
    else
return false;
});

In diesem Beispiel verwenden wir eine anonyme Methode (die wiederum zu komplex ist, um hier erklärt zu werden, aber sie wird in einem anderen Kapitel behandelt werden) als Parameter für die RemoveAll-Methode. Unsere anonyme Methode ist ziemlich einfach - sie wird für jedes Element in der Liste aufgerufen und hat einen Parameter namens name, der natürlich das aktuelle Element in der Iteration ist. Sie schaut sich diesen Namen an und wenn er mit "J" beginnt, wird true zurückgegeben - andernfalls false. Die RemoveAll() - Methode verwendet diese Antwort (true oder false), um zu entscheiden, ob jedes Element entfernt werden soll oder nicht. Am Ende bleibt unsere erste Liste mit nur einem Doe-Mitglied übrig: Another Doe.

Sortieren von Listenelementen

Bisher wurden die Elemente in der Liste, mit denen wir gearbeitet haben, in der Reihenfolge verwendet, in der sie der Liste hinzugefügt wurden. Möglicherweise möchten Sie jedoch, dass die Elemente auf eine bestimmte Weise sortiert werden, z. alphabetisch im Falle unserer Namensliste. Die Liste<T> hat eine Sort() -Methode, die wir dafür verwenden können:

List<string> listOfNames = new List<string>()
{
    "John Doe",
    "Jane Doe",
    "Joe Doe",
    "Another Doe"
};
listOfNames.Sort();
foreach (string name in listOfNames)
    Console.WriteLine(name);

Wie Sie aus der Ausgabe sehen können, wurden die Einträge in der Liste jetzt alphabetisch sortiert. Wenn Sie stattdessen in absteigender Reihenfolge (von Z nach A) möchten, rufen Sie einfach die Reverse() Methode auf Sie führen die Sortierung durch:

listOfNames.Sort();
listOfNames.Reverse();

Also das Sortieren der Liste war ziemlich einfach, oder? Nun, es war hauptsächlich so einfach, weil wir eine Liste von Strings haben und das .NET-Framework genau weiß, wie man zwei Strings vergleicht. Wenn Sie eine Liste mit Zahlen haben, weiß .NET natürlich auch, wie Sie das sortieren können. Es könnte aber sein, dass Sie eine Liste von benutzerdefinierten Objekten haben (da die List<T> jedes Objekt enthalten kann), welches .NET nicht weiß, wie es zu vergleichen ist. Es gibt mehrere Lösungen für dieses Problem, z.B. Implementieren der "IComparable"-Schnittstelle oder Verwenden von LINQ (wir schauen später in diesem Tutorial nach), aber als Schnellkorrektur können wir auch eine Methode zum Aufrufen der Sort() -Methode bereitstellen, um zu erfahren, wie zwei Elemente gegenseitig gestapelt werden, z.B.: so:

using System;
using System.Collections.Generic;

namespace ListSort
{
    class Program
    {
static void Main(string[] args)
{
    List<User> listOfUsers = new List<User>()
    {
new User() { Name = "John Doe", Age = 42 },
new User() { Name = "Jane Doe", Age = 39 },
new User() { Name = "Joe Doe", Age = 13 },
    };
    listOfUsers.Sort(CompareUsers);
    foreach (User user in listOfUsers)
Console.WriteLine(user.Name + ": " + user.Age + " years old");
}

public static int CompareUsers(User user1, User user2)
{
    return user1.Age.CompareTo(user2.Age);
}
    }

    public class User
    {
public string Name { get; set; }
public int Age { get; set; }
    }
}

Dies hat unserem Beispiel einiges an Code hinzugefügt, aber es ist eigentlich nicht zu kompliziert. Wenn wir von unten beginnen, habe ich eine sehr einfache Benutzerklasse erstellt, die aus einem Namen und einem Alter besteht. In der Mitte habe ich eine Methode namens CompareUsers() deklariert - sie nimmt zwei Benutzer als Parameter und gibt dann eine ganze Zahl zurück, die angibt, ob ein Element "kleiner", "gleich" oder " größer "(-1, 0 oder 1) ist. Diese Werte werden von der Sort() -Methode verwendet, um die Elemente zu verschieben, sodass die Reihenfolge der Elemente mit der von uns gewünschten übereinstimmt. In diesem Fall verwende ich einfach die Age-Eigenschaft für den Vergleich und hinterlasse uns im Wesentlichen eine Liste von Nutzern sortiert nach ihrem Alter.

Zusammenfassung

Dieser Artikel ist einer der längeren in diesem Tutorial, aber hoffentlich haben Sie viel über Listen gelernt, denn je mehr Sie programmieren, desto mehr werden Sie feststellen, wie wichtig Listen und Wörterbücher sind. Apropos Wörterbücher, wir besprechen sie im nächsten Artikel.


This article has been fully translated into the following languages: Is your preferred language not on the list? Click here to help us translate this article into your language!