Galileo Computing < openbook > Galileo Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

Inhaltsverzeichnis
Vorwort zur 5. Auflage
1 Allgemeine Einführung in .NET
2 Grundlagen der Sprache C#
3 Klassendesign
4 Vererbung, Polymorphie und Interfaces
5 Delegates und Ereignisse
6 Weitere .NET-Datentypen
7 Weitere Möglichkeiten von C#
8 Auflistungsklassen (Collections)
9 Fehlerbehandlung und Debugging
10 LINQ to Objects
11 Multithreading und die Task Parallel Library (TPL)
12 Arbeiten mit Dateien und Streams
13 Binäre Serialisierung
14 Einige wichtige .NET-Klassen
15 Projektmanagement und Visual Studio 2010
16 XML
17 WPF – Die Grundlagen
18 WPF-Containerelemente
19 WPF-Steuerelemente
20 Konzepte der WPF
21 Datenbindung
22 2D-Grafik
23 ADO.NET – verbindungsorientierte Objekte
24 ADO.NET – Das Command-Objekt
25 ADO.NET – Der SqlDataAdapter
26 ADO.NET – Daten im lokalen Speicher
27 ADO.NET – Aktualisieren der Datenbank
28 Stark typisierte DataSets
29 LINQ to SQL
30 Weitergabe von Anwendungen
Stichwort

Buch bestellen
Ihre Meinung?

Spacer
<< zurück
Visual C# 2010 von Andreas Kühnel
Das umfassende Handbuch
Buch: Visual C# 2010

Visual C# 2010
geb., mit DVD
1295 S., 49,90 Euro
Rheinwerk Computing
ISBN 978-3-8362-1552-7
Pfeil 8 Auflistungsklassen (Collections)
Pfeil 8.1 Die Listen des Namespace »System.Collections«
Pfeil 8.1.1 Die elementaren Schnittstellen der Auflistungsklassen
Pfeil 8.2 Die Klasse »ArrayList«
Pfeil 8.2.1 Einträge hinzufügen
Pfeil 8.2.2 Datenaustausch zwischen einem Array und einer ArrayList
Pfeil 8.2.3 Die Elemente einer ArrayList sortieren
Pfeil 8.2.4 Sortieren von Arrays mit »ArrayList.Adapter«
Pfeil 8.3 Die Klasse »Hashtable«
Pfeil 8.3.1 Methoden und Eigenschaften der Schnittstelle »IDictionary«
Pfeil 8.3.2 Beispielprogramm zur Klasse »Hashtable«
Pfeil 8.4 Die Klassen »Queue« und »Stack«
Pfeil 8.4.1 Die »Stack«-Klasse
Pfeil 8.5 Objektauflistungen im Überblick
Pfeil 8.6 Generische Auflistungsklassen
Pfeil 8.6.1 Die Interfaces der generischen Auflistungsklassen
Pfeil 8.6.2 Die generische Auflistungsklasse »List<T>«
Pfeil 8.7 Eigene Auflistungen mit »yield« durchlaufen


Galileo Computing - Zum Seitenanfang

8.2 Die Klasse »ArrayList« Zur nächsten ÜberschriftZur vorigen Überschrift

ArrayList gehört zu den Klassen, die das Interface IList implementieren. Ein Objekt vom Typ ArrayList hat standardmäßig eine Kapazität von 0 Elementen. Fügen Sie das erste hinzu, wird die Kapazität auf 4 Elemente erhöht. Wird das fünfte Element hinzugefügt, verdoppelt sich die Kapazität automatisch, also auf acht Elemente. Grundsätzlich wird die Kapazität immer verdoppelt, wenn versucht wird, ein Element mehr hinzuzufügen, als es die aktuelle Kapazität erlaubt. Dabei werden die ArrayList-Elemente im Speicher umgeschichtet, was einen Leistungsverlust nach sich zieht, der umso größer ist, je mehr Elemente sich bereits in der ArrayList befinden.

Sie sollten daher von Anfang an der ArrayList eine angemessene Kapazität zubilligen. Das können Sie am besten machen, indem Sie den einfach parametrisierten Konstruktor aufrufen und diesem die gewünschte Anfangskapazität mitteilen. Eine weitere Möglichkeit bietet auch die Eigenschaft Capacity.


Galileo Computing - Zum Seitenanfang

8.2.1 Einträge hinzufügen Zur nächsten ÜberschriftZur vorigen Überschrift

Mit der Methode Add können Objekte einer ArrayList-Instanz hinzugefügt werden. Da ArrayList eine 0-basierte Auflistung ist, wird das erste Element den Index 0 haben, das zweite den Index 1 usw. Sie haben mit der Add-Methode keinen Einfluss darauf, an welcher Position das Objekt in der Liste aufgenommen wird, denn es wird an das Listenende gesetzt. Wollen Sie wissen, welchen Index ein hinzugefügtes Objekt erhalten hat, brauchen Sie nur den Rückgabewert der Add-Methode auszuwerten.


ArrayList liste = new ArrayList();
int index = liste.Add("Conie");

Die Add-Methode ist sehr flexibel und definiert ihren Parameter vom Typ Object. Sie können also alles kunterbunt in die Liste packen, vom String über einen booleschen Wert, von einem Button- bis hin zu einem Circle-Objekt. Spätestens zu dem Zeitpunkt, zu dem Sie die einzelnen Elemente auswerten wollen, werden Sie in Schwierigkeiten geraten, wenn Sie nicht exakt wissen, welcher Typ sich hinter einem bestimmten Element verbirgt. Genau das ist auch der Nachteil der ArrayList. Seien Sie also vorsichtig mit den Elementen – oder nutzen Sie sofort das generische Gegenstück der ArrayList, die Klasse List<T>. Dieser werden wir uns noch später in diesem Kapitel widmen.

Über die Methode Add hinaus bietet ArrayList mit AddRange eine weitere, ähnliche Methode an, der Sie auch ein herkömmliches Array übergeben können:


ArrayList liste = new ArrayList();
int[] array = {0, 10, 22, 9, 45};
liste.AddRange(array);

Liegt das Array schon bei der Instanziierung von ArrayList vor, kann das Array auch direkt dem Konstruktor übergeben werden:


ArrayList arr = new ArrayList(intArr);

Collection-Initialisierer

Eine weitere Möglichkeit, einer ArrayList Elemente hinzuzufügen, sind Collection-Initialisierer. Mithilfe von Collection-Initialisierern kann man bei der Initialisierung eines Collection-Objekts elegant Elemente hinzufügen. Man verwendet geschweifte Klammern, in denen die einzelnen Elemente durch Kommata voneinander getrennt sind – was dann beispielsweise wie folgt aussieht:


ArrayList liste = new ArrayList() {"Aachen", "Bonn", 
                                   "Köln", "Düsseldorf" };

Collection-Initialisierer verringern den Codierungsaufwand ein wenig, da nicht immer wieder die Add-Methode aufgerufen werden muss.

Einträge aus einer ArrayList löschen

Mit der Methode Clear können alle Elemente aus der ArrayList gelöscht werden. Die ArrayList wird danach, obwohl sie leer ist, ihre ursprüngliche Kapazität beibehalten, sie schrumpft also nicht.

Löschen Sie einzelne Elemente, bieten sich die Methoden Remove und RemoveAt an. Remove erwartet das zu löschende Objekt, RemoveAt den Index des zu löschenden Objekts. Beim Löschen ist ein ganz besonderes Verhalten auf der IList basierenden Auflistungen zu erkennen, das wir uns nun in einem Beispiel ansehen wollen.


// -------------------------------------------
// Beispiel: ...\Kapitel 8\ArrayListSample
// -------------------------------------------
using System.Collections;
class Program {
  static void Main(string[] args) {
    ArrayList liste = new ArrayList() {"Peter", "Andreas", 
                                "Conie", "Michael", "Gerd", "Freddy"};
    PrintListe(liste);
    liste.Remove("Andreas");
    Console.WriteLine("--- Element gelöscht ---");
    PrintListe(liste);
    Console.ReadLine();
  }
  static void PrintListe(IList liste) {
    foreach (string item in liste)
      Console.WriteLine("Index: {0,-3}{1}", liste.IndexOf(item), item);
  }
}

Beachten Sie bitte bei diesem und allen anderen Beispielen zu den nichtgenerischen Auflistungsklassen, dass per Vorgabe der Namespace System.Collections.Generic mit using bekannt gegeben ist, wir aber für diese Klassen System.Collections benötigen.

Die Methode PrintListe sorgt für die Ausgabe der Elemente an der Konsole. Das Übergabeargument ist vom Typ IList definiert. Daher könnte die Methode von allen IList implementierenden Klassen benutzt werden, beispielsweise auch von jedem Array – vorausgesetzt, in der Auflistung werden Zeichenfolgen verwaltet.

Nach dem Füllen der Auflistung wird sofort der Inhalt auf der Konsole ausgegeben. Neben der Zeichenfolge wird dabei auch noch der aktuelle Index angezeigt, unter dem die Zeichenfolge eingetragen ist. Der aktuelle Index eines Elements lässt sich mit der Methode IndexOf unter Übergabe des Elements einfach ermitteln.

Nach der Ausgabe der Liste wird das sich an zweiter Position (Index = 1) befindliche Element mit Remove aus der Auflistung gelöscht. Die Ausgabe der aktualisierten Liste entlarvt das eben angedeutete ganz besondere Verhalten der indexbasierten Collections: Der Index, den das aus der Liste gelöschte Element innehatte, bleibt nicht leer. Stattdessen verschieben sich alle nachfolgenden Elemente in der Weise, dass kein leerer Index zurückbleibt (siehe auch Abbildung 8.1).

Abbildung 8.1 Ein Element aus der Auflistung löschen


Hinweis

Sollte sich dasselbe Objekt mehrfach in der Liste befinden, wird nur das Objekt entfernt, das zuerst gefunden wird. Befände sich in dem oben erwähnten Beispiel der Name Andreas auch noch unter Index = 6, wird nur der Eintrag unter dem Index = 1 entfernt. Sie können doppelte Einträge in eine Liste vermeiden, wenn Sie vor dem Hinzufügen des Elements mit Contains prüfen, ob sich das Element eventuell bereits in der Liste befindet.


Möchten Sie während eines Schleifendurchlaufs ein Element aus der Liste löschen, ist eine foreach-Schleife als Schleifenkonstrukt denkbar ungeeignet, denn die Methoden des Interface IEnumerator funktionieren nur dann, wenn sich die Liste während des Schleifendurchlaufs nicht verändert.

Eine Lösung in solchen Fällen ist die Verwendung der for- oder while-Schleife, z. B.:


for(int index = 0; index < liste .Count;index++)
  if( (string)liste[index] == "Andreas")
    liste.RemoveAt(index);

Auf ein Listenelement wird über seinen Index zugegriffen, indem der Index in eckige Klammern gesetzt wird. Da die Elemente als Object-Typen in die ArrayList eingetragen werden, ist eine Konvertierung in den passenden Typ notwenig, in unserem Code also in string.


Galileo Computing - Zum Seitenanfang

8.2.2 Datenaustausch zwischen einem Array und einer ArrayList Zur nächsten ÜberschriftZur vorigen Überschrift

Auflistungen zeichnen sich durch die beiden Interfaces IEnumerable und ICollection aus. Aus dem letztgenannten Interface stammt die Methode CopyTo, die es ermöglicht, die Einträge einer Auflistung in ein Array zu kopieren.


ArrayList liste = new ArrayList();
liste.Add("Anton");
liste.Add("Gustaf");
liste.Add("Fritz");
string[] arr = new string[10];
liste.CopyTo(arr, 3);

Der zweite Parameter von CopyTo gibt den Startindex im Array an, ab dem die Elemente der ArrayList in das Array kopiert werden. Das Array muss groß genug sein, um alle Elemente aufzunehmen, sonst wird eine Exception ausgelöst. Handelt es sich bei den zu kopierenden Einträgen um Objektreferenzen, werden nicht die Objekte, sondern nur die Referenzen kopiert. ArrayList überlädt CopyTo, sodass auch spezifizierte Teilbereiche der Liste kopiert werden können.


Galileo Computing - Zum Seitenanfang

8.2.3 Die Elemente einer ArrayList sortieren Zur nächsten ÜberschriftZur vorigen Überschrift

Um die Mitglieder einer ArrayList zu sortieren, wird die Methode Sort aufgerufen. Sort ist mehrfach überladen. Wir wollen uns zunächst mit der parameterlosen Version beschäftigen.

Die parameterlose »Sort«-Methode

Um die Elemente einer ArrayList mit der parameterlosen Sort-Methode zu sortieren, müssen die Typdefinitionen der Elemente die Schnittstelle IComparable implementieren. Diese Schnittstelle beschreibt nur die Methode CompareTo:


public interface IComparable {
  int CompareTo(object obj);
}

Eine Klasse, die IComparable implementiert, garantiert, dass die Methode CompareTo existiert. Darauf ist die Sort-Methode der ArrayList angewiesen. Aus der .NET-Dokumentation zu CompareTo können wir entnehmen, dass das Objekt, auf dem Sort aufgerufen wird, mit dem an den Parameter übergebenen Objekt verglichen wird. Als Resultat liefert der Methodenaufruf eines der drei folgenden Ergebnisse:

  • < 0, wenn das aktuelle Objekt kleiner als das Objekt obj ist
  • 0, wenn das aktuelle Objekt gleich dem Objekt obj ist
  • > 0, wenn das aktuelle Objekt größer als das Objekt obj ist

Die Regel, nach der im deutschsprachigen Raum sortiert wird, vergleicht die Zeichen unter Berücksichtigung der Groß- und Kleinschreibung wie folgt:


1 < 2 ... < a < A < b < B < c < C ... < y < Y < z < Z

Alle Klassen, die IComparable implementieren, sind daher ohne weiteres Coding dazu geeignet, innerhalb einer ArrayList sortiert zu werden. Das trifft insbesondere auf die elementaren Datentypen wie string, int oder double zu. Somit ist es uns auch möglich, die Listenelemente aus dem Beispiel ArrayListSample durch den Aufruf von Sort unkompliziert sortieren zu lassen.


static void Main(string[] args) {
  ArrayList liste = new ArrayList() {"Peter", "Andreas", "Conie", 
                                     "Michael", "Gerd", "Freddy"};
  liste.Sort();
  PrintListe(liste);
  Console.ReadLine();
}

Die Ausgabe der sortierten Liste sehen Sie in Abbildung 8.2.

Abbildung 8.2 Sortierte Listenelemente

Eigene Klassen mit »IComparable«

Viele Klassen des .NET Frameworks implementieren die IComparable-Schnittstelle. Das folgende Beispielprogramm soll zeigen, wie Sie dieses Interface für eigene Klassen einsetzen können. Dabei werden wir der Einfachheit halber nur mit einer sehr einfachen Klasse arbeiten, die neben der Schnittstellenimplementierung nur einen Integer-Wert in der Eigenschaft Value beschreibt und einen parametrisierten Konstruktor.


public class Demo : IComparable {
  public int Value {get; set;}
  public Demo(int value) {
    Value = value;
  }
  public int CompareTo(object obj) {
    if (((Demo)obj).Value < Value)
      return 1;
    else if (((Demo)obj).Value == Value)
      return 0;
    return -1;
  }
}

Die Klasse Demo implementiert IComparable. Daher sind Objekte dieses Typs darauf vorbereitet, in einer ArrayList sortiert zu werden. Die Sortierreihenfolge soll sich am Inhalt des Felds Value orientieren. Da CompareTo den Parameter vom Typ Object definiert, muss vor dem Zugriff auf das Feld Value eine Typkonvertierung erfolgen. Die Bildung des Rückgabewertes bedarf keiner weiteren Beschreibung. Bei aller Einfachheit sollten Sie sich jedoch darüber im Klaren sein, dass Sie die Entscheidung selbst treffen, unter welchen Umständen die zu vergleichenden Objekte als größer, gleich oder kleiner einzustufen sind.


Anmerkung

So, wie das Vergleichskriterium in diesem Beispiel formuliert ist, könnten wir auch die Schnittstelle IComparable des Integers für unsere Zwecke nutzen, und mit

return Value.CompareTo(((Demo)obj).Value);

einen deutlich kürzeren Code erzeugen. Allerdings würde dann diesem Beispiel die Allgemeingültigkeit fehlen.


Mit der Implementierung der Methode CompareTo können wir uns aber noch nicht zufriedengeben, da nicht alle denkbaren Szenarien von unserer Implementierung berücksichtigt werden. Sie könnten nämlich auch ein Objekt übergeben, das mit dem aktuellen nicht vergleichbar ist, beispielsweise:


Circle kreis = new Circle(5);
Demo element = new Demo(8);
int result = element.CompareTo(kreis);
...

Implementieren Sie die Methode CompareTo, sollten Sie diesen Fall ebenso berücksichtigen wie die Eventualität, dass das übergebene Objekt noch nicht initialisiert und daher null ist. Die Implementierung, die diese beiden Szenarien einbezieht, sieht wie folgt aus:


public int CompareTo(object obj) {
  // prüfen, ob der Parameter ein null-Verweis ist
  if (obj == null)
    return 1; 
  // prüfen, ob beide Typen gleich sind
  if (obj.GetType() != GetType())
    throw new ArgumentException("Ungültiger Vergleich.");
  if (((Demo)obj).Value < this.Value)
    return 1;
  else if (((Demo)obj).Value == this.Value)
    return 0;
  return -1;
}

Generell sollten Sie die Methode CompareTo der Schnittstelle IComparable wie gezeigt implementieren, um gegen alle unzulässigen Aufrufe gewappnet zu sein und als robust zu gelten. Es wird zuerst überprüft, ob dem Parameter null übergeben wurde. In diesem Fall sollte der Vergleich abgebrochen werden und als Resultat einen Wert größer 0 liefern. Unterscheiden sich die beiden Typen des anstehenden Vergleichs, wird die Ausnahme ArgumentException ausgelöst und muss vom Aufrufer behandelt werden.

Natürlich wollen wir nun auch testen, ob wir unser Ziel erreicht haben. Dazu dient der folgende Code:


// -------------------------------------------
// Beispiel: ...\Kapitel 8\IComparableSample
// -------------------------------------------
class Program {
  static void Main(string[] args) {
    Demo[] arr = new Demo[] { new Demo(12), new Demo(27), 
                              new Demo(35), new Demo(3) };
    ArrayList liste = new ArrayList();
    liste.AddRange(arr);     
    liste.Sort();
    foreach (Demo item in liste) {
      Console.WriteLine("Index: {0} / Wert: {1}", 
                         liste.IndexOf(item), item.Value);
    }
    Console.ReadLine();
  }
}

An der Konsole werden die Werte der Felder in der Reihenfolge 3, 13, 27 und 35 ausgegeben. Der Vergleich und die anschließende Sortierung finden also wie erwartet statt.

Vergleichsklassen mit »IComparer«

Das Sortieren einer ArrayList mit der parameterlosen Sort-Methode gestattet nur ein Vergleichskriterium. Manchmal ist es aber erforderlich, unterschiedliche Sortierkriterien zu berücksichtigen. Nehmen wir zum Beispiel die Klasse Person, die die beiden Felder Name und Wohnort beschreibt:


class Person {
  public string Name {get; set;}
  public string Wohnort {get; set;}
  public Person(string name, string ort) {
    Name = name;
    Wohnort = ort;
  }
}

Würde die Klasse die Schnittstelle IComparable implementieren, müsste die Entscheidung getroffen werden, nach welchem Feld Objekte dieser Klasse sortiert werden können. Nun sollen beide Möglichkeiten angeboten werden: sowohl die Sortierung nach Wohnort als auch nach Name.

Die Lösung des Problems führt über die Bereitstellung sogenannter Vergleichsklassen, die die Schnittstelle IComparer implementieren. Jede Vergleichsklasse beschreibt genau ein Vergleichskriterium. Wollen wir einen bestimmten Objektvergleich erzwingen, müssen wir der Sort-Methode mitteilen, welche Vergleichsklasse dafür bestimmt ist. Dafür stehen uns zwei Überladungen zur Verfügung, denen die Referenz auf ein Objekt übergeben wird, das die Schnittstelle IComparer implementiert:


public virtual void Sort(IComparer);
public virtual void Sort(int, int, IComparer);

Mit der Überladung, die zwei Integer erwartet, kann der Startindex und die Länge des zu sortierenden Bereichs bestimmt werden. Bei sehr großen Auflistungen steigert das die Performance, da Sortiervorgänge sehr rechenintensiv sind.

Die Schnittstelle IComparer stellt die Methode Compare für den Vergleich zweier Objekte bereit:


int Compare(object x, object y);

Compare funktioniert ähnlich wie die weiter oben erörterte Methode CompareTo und gibt die folgenden Werte zurück:

  • < 0, wenn das erste Objekt kleiner als das zweite Objekt ist
  • 0, wenn das erste Objekt gleich dem zweiten Objekt ist
  • > 0, wenn das erste Objekt größer als das zweite Objekt ist

Für die Klasse Person wollen wir nun die beiden Vergleichsklassen NameComparer und WohnortComparer entwickeln, die gemäß unserer Anforderung die Schnittstelle IComparer implementieren und nach Wohnort bzw. Name sortieren.


// Vergleichsklasse - Kriterium 'Wohnort'
class WohnortComparer : IComparer {
  public int Compare(object x, object y) {
    // prüfen auf null-Übergabe
    if(x == null && y == null) return 0;
    if(x == null) return 1;
    if(y == null) return -1; 
    // Typüberprüfung
    if(x.GetType() != y.GetType())
      throw new ArgumentException("Ungültiger Vergleich");
    // Vergleich
    return ((Person)x).Wohnort.CompareTo(((Person)y).Wohnort);
  }
}
// Vergleichsklasse - Kriterium 'Name'
class NameComparer : IComparer {
  public int Compare(object x, object y) {
    // prüfen auf null-Übergabe
    if(x == null && y == null) return 0;
    if(x == null) return 1;
    if(y == null) return -1; 
    // Typüberprüfung
    if(x.GetType() != y.GetType())
      throw new ArgumentException("Ungültiger Vergleich");
    // Vergleich
    return ((Person)x).Name.CompareTo(((Person)y).Name);
  }
}

Die Implementierung ähnelt der der Methode CompareTo. Zuerst sollte wieder ein Vergleich mit null durchgeführt werden und anschließend eine Prüfung, ob beide Parameter denselben Typ beschreiben oder zumindest einen vergleichbaren Typ besitzen. Sollte keine Bedingung zutreffen, kann der Vergleich der Objekte erfolgen. Dabei unterstützt uns die Klasse String, die ihrerseits die IComparable-Schnittstelle implementiert und folglich die Methode CompareTo veröffentlicht.

Haben wir ein ArrayList-Objekt mit Person-Objekten gefüllt, steht es uns frei, welche Vergleichsklasse wir zur Sortierung der Objekte benutzen, denn beide sind auf dieselbe Schnittstelle zurückzuführen und gegenseitig austauschbar.

Natürlich können Sie auch jederzeit die Klasse Person um die Schnittstelle IComparer erweitern. Syntaktisch bereitet das zumindest bei einem erforderlichen Vergleichskriterium überhaupt kein Problem. Andererseits müssen Sie sich auch vor Augen halten, wie Sie die Sort-Methode aufrufen müssten:


liste.Sort(new Person());

Dieser Code suggeriert, dass wir es mit einem weiteren, neuen Person-Objekt zu tun haben, obwohl wir das Objekt doch eigentlich nur dazu missbrauchen, das Vergleichskriterium der Sort-Methode bekannt zu geben. Ähnlich schlecht les- und interpretierbarer Code wäre das Resultat, wenn wir mit


liste.Sort(person1);

irgendein bekanntes Person-Objekt übergeben. Daher sollten Sie von dieser Codeimplementierung Abstand nehmen.

Sehen wir uns nun das Beispielprogramm an, in dem die oben beschriebenen Vergleichskriterien benutzt werden.


// ---------------------------------------------------------
// Beispiel: ...\Kapitel 8\IComparerSample
// ---------------------------------------------------------
class Program {
  static void Main(string[] args) {
    ArrayList arrList = new ArrayList();
    // ArrayList füllen
    Person pers1 = new Person("Meier", "Berlin");
    arrList.Add(pers1);
    Person pers2 = new Person("Arnhold", "Köln");
    arrList.Add(pers2);
    Person pers3 = new Person("Graubär", "Aachen");
    arrList.Add(pers3); 
    // nach Wohnorten sortieren
    arrList.Sort(new WohnortComparer());
    Console.WriteLine("Liste nach Wohnorten sortiert");
    ShowSortedList(arrList); 
    // nach Namen sortieren
    arrList.Sort(new NameComparer());
    Console.WriteLine("Liste nach Namen sortiert");
    ShowSortedList(arrList);
  }
  static void ShowSortedList(IList liste) {
    foreach(Person temp in liste) {
      Console.Write("Name = {0,-12}", temp.Name);
      Console.WriteLine("Wohnort = {0}", temp.Wohnort);
    }
    Console.WriteLine();
  }
}

Abbildung 8.3 Ausgabe des Beispiels »IComparerSample«


Galileo Computing - Zum Seitenanfang

8.2.4 Sortieren von Arrays mit »ArrayList.Adapter« topZur vorigen Überschrift

Ein herkömmliches Array bietet von Haus aus keine Möglichkeit, die in ihm enthaltenen Elemente zu sortieren. Es gibt dennoch einen Weg, der über die klassische Methode Adapter der Klasse ArrayList führt.


public static ArrayList Adapter(IList list);

Der Methode wird ein IList-Objekt übergeben. Der Zufall will es, dass ein klassisches Array diese Schnittstelle implementiert. Adapter legt einen Wrapper (darunter ist eine Klasse zu verstehen, die sich um eine andere legt) um das IList-Objekt. Der Rückgabewert ist die Referenz auf ein neues ArrayList-Objekt, mit dessen Methoden, unter anderem auch Sort, sich das IList-Objekt manipulieren lässt.

Wie Sie die Methode Adapter einsetzen können, möchte ich Ihnen an einem Beispiel zeigen. Dabei dient wieder die Klasse Person aus dem Beispiel IComparerSample als Grundlage. Zudem soll auch wieder die Möglichkeit eröffnet werden, entweder nach Namen oder Wohnort sortieren zu können. Dazu können Sie die ebenfalls vorhandenen Vergleichsklassen des Beispiels aus dem letzten Abschnitt wiederverwenden.


// -----------------------------------------------------------
// Beispiel: ...\Kapitel 8\ArrayListAdapterSample
// -----------------------------------------------------------
class Program {
  static void Main(string[] args){
    Person[] pers = new Person[3];
    pers[0] = new Person("Peter", "Celle");
    pers[1] = new Person("Alfred", "München");
    pers[2] = new Person("Hugo", "Aachen");
    ArrayList liste = ArrayList.Adapter(pers);
    // Sortierung nach Namen
    liste.Sort(new NameComparer());
    Console.WriteLine("Sortiert nach den Namen:");
    for (int index = 0; index < 3; index ++)
      if( liste[index] != null)
        Console.WriteLine(((Person)liste[index]).Name);
    // Sortierung nach Wohnort
    Console.WriteLine("\nSortiert nach dem Wohnort:");
    liste.Sort(new WohnortComparer());
    for (int index = 0; index < 3; index ++)
      if( liste[index] != null)
        Console.WriteLine(((Person)liste[index]).Wohnort);
    Console.ReadLine();
  }
}

Bei der Ausgabe der sortierten Listenelemente müssen wir ein wenig vorsichtiger sein. Denn im Gegensatz zur ArrayList, die uns garantiert, dass sich hinter jedem Index ein gültiges Objekt verbirgt, kann der Index in einem klassischen Array null sein. Der Versuch einer Ausgabe oder ganz allgemein des Zugriffs auf ein null-Element würde mit einer Ausnahme quittiert werden. Daher ist unbedingt darauf zu achten, vor der Ausgabe mit


if (liste[index] != null)

auf den Inhalt null zu prüfen.



Ihr Kommentar

Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen. >> Zum Feedback-Formular
<< zurück
  Zum Katalog
Zum Katalog: Visual C# 2010

Visual C# 2010
Jetzt bestellen


 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Buchempfehlungen
Zum Katalog: Professionell entwickeln mit Visual C# 2012






 Professionell
 entwickeln mit
 Visual C# 2012


Zum Katalog: Windows Presentation Foundation






 Windows Presentation
 Foundation


Zum Katalog: Schrödinger programmiert C++






 Schrödinger
 programmiert C++


Zum Katalog: C++ Handbuch






 C++ Handbuch


Zum Katalog: C/C++






 C/C++


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo




Copyright © Rheinwerk Verlag GmbH 2010
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


Nutzungsbestimmungen | Datenschutz | Impressum

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de

Cookie-Einstellungen ändern