Lambda Expressions

Die Lambda Expressions sind ein neues Feature von C# 3.0. Sie stellen Funktionen dar, die zur Laufzeit bereits kompiliert worden sind oder kompiliert werden können. Überall wo man in C# 2.0 eine Delegate schreiben musste, kann man in C# 3.0 auch eine Lambda Expressions benutzen.

Ohne grosse verbale Abhandlungen, versuche ich den Syntax von Lambda an ein paar einfachen Beispielen zu erklären…

Beispiel einer Delegate mit einem Parameter:

delegate int Calculator(int i);
Calculator square = delegate(int x) {return x * x;};
int result = square(3);   // Ergibt 9

Beispiel einer Lambda-Funktion mit einem Parameter

delegate int Calculator(int i);
Calculator square = x => x * x;
int result = square(3);   // Ergibt 9

Beispiel mit zwei Parameter:

delegate int Calculator(int i, int k);
Calculator multiply = (x,y) => x * y;
int result = multiply(3,4);   // Ergibt12

Beispiel einer Operation ohne Parameter

delegate int Sequence();
int seed = 0;
Sequence counter = () => seed++;
counter();   // seed ist 1
counter();   // seed ist 2

Wie man erkennen kann, beschreibt die Definitionen vor dem Lambda-Operator „=>“ die jeweiligen Parameter. Formal betrachtet könnte man den Lambda-Syntax folgendermassen beschreiben:(input parameters) => expression resp. (input parameters) => {statement;}

Wie man sieht, sind Lambda Funktionen und Expressions sind extrem allgemein gehalten. Wie man Lambda-Ausdrücke dynamisch on-the-fly erzeugen kann, werde ich in einem späteren Artikel erklären. Dies ist dann schon ein wenig komplexer.

Das generische Func<> delegate

Wie man oben gesehen hat, werden Lambda-Ausdrücke in delegates übersetzt, um ausgeführt zu werden. Um nicht für jede Funktion eine delegate zu deklarieren (wie oben), gibt es neu die generischen Func<> delegates. Damit lassen sich die eigenen Deklarationen zu einem grossen Teil eleminieren und muss nicht auf die Typsicherheit verzichten.

Beispiel:

Func<int, int> square = x => x * x;
int result = square(3);   // Ergibt 9

Folgende 5 verschiedene Func<> delegates gibt es:

public delegate TResult Func<TResult>();
public delegate TResult Func<T, TResult>(T arg);
public delegate TResult Func<T1, T2, TResult>(T1 arg1, T2 arg2);
public delegate TResult Func<T1, T2, T3, TResult>(T1 arg1, T2 arg2, T3 arg3);
public delegate TResult Func<T1, T2, T3, T4, TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);

Damit lassen sich somit Funktionen bis zu 4 Parameter abdecken, ohne eigene Delegates zu deklarieren.

Das generische Action<> delegate

Das generische Action<> delegate ist dem Func<> sehr ähnlich. Der einzige Unterschied befindet sich darin, dass Func<> eine Funktion ist und einen Rückgabewert besitzt. Der Rückgabewert von Action<> ist immer void.

Beispiel:

Action<string> writeCons = x => Console.WriteLine(x.ToString());
writeCons(„Test“);

Die 4 verschiedenen Action<> delegates lassen vermuten, dass es sich hierbei auch wiederum um eine Vereinfachung für den Entwickler handelt. Delegates bis zu 4 Parameter braucht man nicht mehr selber zu deklarieren, sondern kann die generischen Standard-Delegates vom System-Namespace nehmen.

public delegate void Action<T>(T obj);
public delegate void Action<T1, T2>(T1 arg1, T2 arg2);
public delegate void Action<T1, T2, T3>(T1 arg1, T2 arg2, T3 arg3);
public delegate void Action<T1, T2, T3, T4>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);

Wichtiger Hinweis

Anfänglich ist der gebraucht von Lambda extrem umständlich und verwirrend. Der Quellcode sieht zu beginn auch sehr befrendend, seltsam und unübersichtlich aus. Doch das ist normal und man gewöhnt sich recht schnell daran (…wie ehem. VB-Programmierer an die C#-Klammern – gell Urs!). Lambda ist meines Erachtens eine super Sache und erleichtert die Programmierung und Übersicht merklich. Zudem sind Lambda-Ausdrücke und das Verständnis, wie sie funktionieren für LINQ unabdingbar. Ohne Lambda kein LINQ!

2 Gedanken zu „Lambda Expressions

  1. Hoi Jürgl

    Mal guggen, ob ich mich an Lambda auch so schnell (oder langsam) gewöhnen werde, wie an die geschweiften Klammern 😉

    tschaui
    U.

Kommentare sind geschlossen.