Einige meiner Lieblingsklassen
System.Collections.ArrayList
Oft benötige ich eine liste von Objekten und die
ArrayList ist geradezu perfekt für solche Situationen. Es gibt verschiedene Situationen, für welche ich die
ArrayList nutze.
Oft kopiere ich zum Beispiel die Inhalt einer
ArrayListe in ein Array Objekt:
Delphi-Quellcode:
var
MyList: ArrayList;
MyStrs: array of string;
begin
MyList := ArrayList.Create;
MyList.Add('Hello');
MyList.Add('World');
MyList.Add('Foo');
SetLength(MyStrs, MyList.Count);
MyList.CopyTo(MyStrs);
end;
Der Vorteil dieser Methode ist, dass man den gesamten Inhalt der
ArrayListe in einem typisierten Array hat. Man beachte, dass dieses Beispiel zur Laufzeit einen Ausnahmefehler erzeugen würden, wenn in der
ArrayListe andere Werte als Strings enthalten sind. Desweiteren muss immer sicher gestellt sein, dass das Array groß genügend ist, um die Werte der
ArrayListe aufzunehmen. In obigem Beispiel wird das durch den Aufruf zu
SetLength sicher gestellt.
Ein weiterer wichtiger Punkt ist, das ein dynamisches Delphi-Array (hier: "array of string") und das
System.Array des .NET Framework äquivalent sind.
Ich nutze die
ArrayList auch desöfteren, um Elemente zu sortieren. Die Methode [i]Sort[i] ist die Standardimplementierung, um diese Aufgabe zu erledigen und meist reicht diese auch aus. Sollte man jedoch Objekte haben, welche sich nicht einfach sortieren lassen, so kann man die Schnittstelle
IComparer implementieren und diese an
ArrayList.Sort(IComparer) übergeben.
Die Implementierung ist einfach; es muss nur eine Methode
Compare(...) zur Verfügung gestellt werden. Diese sollte einen Wert kleiner 0 zurückliefern, wenn das erste Objekt kleiner ist als das zweite Objekt, 0 wenn diese gleich sind und einen Wert größer als 0, wenn das erste Objekt größer ist als das zweite.
Die [i]ArrayList[i] Klasse implementiert die
IList Schnittstelle, welche von
IEnumerable abgeleitet ist. Jede Klasse, welche
IEnumerable implementiert kann auch sehr einfach durchlaufen werden. Man muss sich nur merken, wie man dieses tut.
Code:
[i]// in C#[/i]
[b]foreach [/b]([b]object [/b]foo [b]in [/b]myArrayList) [b]do[/b]
[i]// Do something with foo[/i]
Delphi-Quellcode:
// in Delphi 9 (ähnlich, allerdings muss Foo deklariert werden)
var
Foo: System.Object;
begin
...
for Foo in MyArrayList do
// Do something with Foo
System.Collections.Hashtable
Ich liebe Hashtabellen und nutze diese überall und immer wieder. Die Implementierung dieser durch die
FCL ist so flexibel gehalten, dass auch Du diese bald genauso nutzen wirst.
Die Benutzung einer Hashtabelle ist sehr einfach:
Delphi-Quellcode:
var
MyHash: Hashtable;
MyObj: System.
Object;
MyInt: Integer;
begin
MyHash := Hashtable.Create;
MyHash['
Key1'] := Self;
{ Overwrite the value }
MyHash['
Key1'] := 1;
{ Access the value }
MyObj := MyHash['
Key1'];
{ We know it is an integer }
if MyObj <>
nil then
MyInt := Integer(MyObj);
{ Set the value to nil; 'Key1' still exists in the hashtable }
MyHash['
Key1'] :=
nil;
{ Remove it from the hashtable }
MyHash.Remove('
Key1');
end;
Es gibt allerdings ein paar Dinge, welche berücksichtigt werden sollten. Erstens, wird ein Schlüssel/Wert auf
nil gesetzt, so wird der Schlüssel nicht aus der Hashtabelle entfernt, dazu muss die Methode
Remove(Schlüssel) aufgerufen werden. Will man alle Schlüssel/Werte-Paare durchlaufen, so kann man auf die Keys bzw. auf die Werteeigenschaften der Hashtabelle zugreifen:
Delphi-Quellcode:
for Obj in MyHash.Keys do
Console.Write(Obj.ToString);
Will man auf alle Schlüssel/Werte-Paare zugreifen, so muss man die Schnittstelle
IDictionaryEnumerator manuell ansprechen:
Delphi-Quellcode:
var
MyHash: Hashtable;
Enumerator: IDictionaryEnumerator;
begin
MyHash := Hashtable.Create;
...
Enumerator := MyHash.GetEnumerator;
while Enumerator.MoveNext do
begin
Console.WriteLine('Key: ' + Enumerator.Key.ToString);
Console.WriteLine('Value: ' + Enumerator.Value.ToString);
end;
end;
System.Diagnostics
Oft will man sicherstellen, dass der geschriebene Code auch korrekt ist. Nutzt man den Namensraum
System.Diagnostics kann man jederzeit auf die Klasse
Debug und die statischen Variablen zugreifen um
Asserts durchzuführen:
Debug.Assert(foo = bar, 'Foo should be equal to bar');
Wird ein Assert ausgeführt, so kann man in einem Debugger leicht erkennen, warum ein Assert eine Meldung ausgibt. Ich nutze diese Debuggingmethode ständig und finde diese unentbehrlich.