Delegates und anonyme Methoden (Teil 2)
Kommentare

Weniger Ballast – Anonymous Methods
Die zuvor gezeigten Beispiele verdeutlichten die Arbeitsweise von Funktionszeigern mit benannten Methoden. Die generelle Anlage einer separaten Methode, die durch den

Weniger Ballast – Anonymous Methods

Die zuvor gezeigten Beispiele verdeutlichten die Arbeitsweise von Funktionszeigern mit benannten Methoden. Die generelle Anlage einer separaten Methode, die durch den Delegate aufgerufen werden soll, wirkt sich aber teilweise negativ auf die Qualität des Quellcodes aus. Die Implementierung in Listing 3 ist dafür ein typisches Beispiel. Betrachtet man die Anweisung List result = arr.FindAll(new Predicate(IsMatch));, wird nicht ersichtlich, welche Zahlen gefunden werden sollen. Um das herauszufinden, muss innerhalb des Quellcodes zur Methode IsMatch gesprungen werden. Das stellt einen erheblichen Nachteil dar und führt zu einer Fragmentierung der Logik innerhalb des Quellcodes. Besser ist es daher, die Logik nah am Ort der Verwendung zu hinterlegen, genau das ist mit anonymen Methoden möglich. Anonyme Methoden fanden mit der .NET-Version 2.0 Einzug in die C#-Welt. Mithilfe dieses in C# neuen Sprachkonstrukts können Methoden realisiert werden, die keinen Namen besitzen. Das hört sich erst einmal nachteilig an, da ohne Name keine direkte Referenz auf die Methode besteht. Dennoch helfen gerade diese Methoden, den Code wesentlich lesbarer zu gestalten als mit benannten Methoden. Listing 5 zeigt die Verwendung einer anonymen Methode.

static List arr = new List { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 
                                       13, 14, 15, 16, 17, 18, 19, 20 };
public static void Test()
{
  List result = arr.FindAll(delegate(int figure)
  {
    return (figure % 2) == 0;
  });
}  

Listing 5

Eingeleitet wird die anonyme Methode mit dem Schlüsselwort delegate, gefolgt von – wenn vorhanden – Parametern. Wie hier erkennbar ist, können auch generische Parameter verwendet werden. Im anschließenden Codeblock wird die nötige Logik hinterlegt. Durch die Verwendung einer anonymen Methode wird der Quellcode lesbarer. Nun ist sofort ersichtlich, welche Zahlen von dem Aufruf zurückgeliefert werden. Anonyme Methoden können an vielen Stellen des .NET Frameworks verwendet werden. Innerhalb einer WinForms-Anwendung kann z. B. das Klickereignis auf einer Schaltfläche durch eine anonyme Methode behandelt werden:

btnCancel.Click += delegate(object sender,EventArgs args) { MessageBox.Show("Abbruch"); };

Weitere Beispiele und Erläuterungen sind unter [2] abrufbar.

Interne Funktionsweise

Je nachdem, welche Parameter und Variablen eine anonyme Methode verwendet, variiert der Code, der vom Compiler erzeugt wird. Eine anonyme Methode kann lokale Variablen nutzen, solche, die über Parameter übergeben wurden, oder auch global verfügbare Variablen. Im einfachsten Fall verwendet die anonyme Methode nur interne Variablen. Listing 6 zeigt dazu eine entsprechende anonyme Methode. In diesem Fall fügt der Compiler während der Übersetzungszeit der Klasse eine neue private Methode mit folgender Signatur hinzu: [Rückgabetyp] [Äußeren Methodennamen][Eindeutigen Namen]_[Anzahl Parameter].

delegate void CallBack();
public static void Listing6()
{
  CallBack cb = delegate()
  { Console.WriteLine("Hello"); };
  cb();
}  

Listing 6

Listing 7 zeigt den vollständigen MSIL-Code der erzeugten privaten Methode.

.method private hidebysig static void b__0() cil managed
{
    .custom instance void [mscorlib]System.Runtime.CompilerServices.
     CompilerGeneratedAttribute::.ctor()
    .maxstack 8
    L_0000: ldstr "Hello"
    L_0005: call void [mscorlib]System.Console::WriteLine(string)
    L_000a: ret 
}  

Listing 7

Dann ermittelt der Compiler mittels Delegate Inference den Typ des Delegaten, legt diesen an und übergibt den Namen der neu erzeugten privaten Methode. Verwendet die anonyme Methode darüber hinaus äußere Variablen, wird der erzeugte MSIL-Code komplexer. Hierbei muss der Compiler zunächst eine neue interne Klasse anlegen, in der dann wiederum die neue Methode angelegt wird. Wie aus der Beschreibung erkennbar wird, vervollständigt der Compiler automatisch die „fehlenden“ Implementierungen. Aus Sicht des MSIL-Codes existieren daher eigentlich keine anonymen Methoden.

Zusammenfassung

Anonyme Methoden können helfen, den Quellcode übersichtlicher und strukturierter zu organisieren. Sie sollten aber wirklich nur dann verwendet werden, wenn die Methode nur einmalig benötigt wird. Sobald die Methode an mehreren Stellen aufgerufen werden muss, darf – gemäß dem DRY-(Don’t-Repeat-Yourself-)Prinzip – keine anonyme Methode verwendet werden. In diesem Fall muss zwingend eine benannte Methode implementiert werden.

Marc André Zhou arbeitet als Senior Consultant bei der Logica Deutschland GmbH & Co. KG. Seine Schwerpunkte liegen im Bereich Softwarearchitekturen und Frameworks, hier hauptsächlich im .NET-Umfeld. Sie erreichen ihn per E-Mail.
Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -