Jetzt muss ich mal ein bisschen was zusammenschreiben zum Thema Lamda Expressions. Seit die Lamdas mit .NET 3.0 eingeführt wurden, nehme ich sie regelmäßig her, hab mir aber ehrlich gesagt nicht wirklich Gedanken darüber gemacht, was das eigentlich ist.

Daher erst einmal eine Erklärung um was es sich dabei handelt:

Bei Lamda Expessions handelt es sich genau genommen nicht um ein Feature, das mit .NET 3.0 eingeführt wurde sondern lediglich um eine alternative Schreibweise um anonyme Methode anders darzustellen und in vielen Fällen vor allem kürzer darzustellen.

Nehmen wir mal als Beispiel eine kleine Methode, die mit beliebig vielen Zahlen eine Rechenoperation durchführen soll, wobei für diese Operation immer nur zwei Zahlen herangezogen werden.

private delegate int MyMethod(int a, int b);
private int MultiCalculator(MyMethod m, params int[] values)
{
    int result = 1;
    foreach (int v in values)
        result = m(result, v)
    return result
}

Die Methode “MultiCalculator” nimmt als eine beliebige Anzahl von Integer und schiebt diese Integer jeweils durch die Methode m die durch einen Delegate definiert ist.

Jetzt schreiben wir noch zwei Methoden, um zu zeigen, wie der Aufruf mit benannten Methoden aussehen würde:

private int Add(int a, int b) { return a + b; }
private int Multiply(int a, int b) { return a * b; }

Also eine Methode zum Addieren der Zahlen und eine zum Multiplizieren der Zahlen.

Wenn man jetzt die Methode MultiCalculator ausführen will, sieht der Aufruf folgendermaßen aus:

int resultAdd = MultiCalculator(Add, 1, 2, 3, 4, 5);
// => 16 (man beachte die 1 mit der das Result im MultiCalculator vorbelegt ist)
int resultMultiply = MultiCalculator(Multiply, 1, 2, 3, 4, 5);
// => 120

So. Im nächsten Schritt entfernen wir wieder die Methode Add und Multiply, weil wir das ganze mit anonymen Methoden durchziehen wollen. Da jetzt keine Methode mehr vorgegeben ist, muss man den Delegaten im Aufruf definieren. Das Ganze sieht dann so aus:

int resultAdd = MultiCalculator(delegate(int a, int b) { return a + b; }, 1, 2, 3, 4, 5);
// => 16
int resultMultiply = MultiCalculator(delegate(int a, int b) { return a * b; }, 1, 2, 3, 4, 5);
// => 120

Das sieht jetzt nicht wirklich besser aus, aber man spart sich zumindest das Erstellen von zwei zusätzlichen Methoden, die vielleicht sonst auch nirgends gebraucht werden.

Jetzt machen wir das gleiche nochmal mit Lamda Expressions, wo wir ja eigentlich hin wollen.

int resultAdd = MultiCalculator((a, b) => a + b, 1, 2, 3, 4, 5);
// => 16
int resultMultiply = Multicalculator((a, b) => a * b, 1, 2, 3, 4, 5);
// => 120

Man sieht also, dass es genau genommen immer noch die gleiche Schreibweise bzw. Denkweise ist, aber jetzt erheblich kürzer gemacht ist. Es werden keine Typen mehr doppel definiert, da diese ja bereits in der Delegaten-Definition genannt wurden. Außerdem spart man sich ein paar Schlüsselwörter.

Man sollte dabei aber auch wissen, dass intern dennoch wieder das Ganze aufgetrennt wird. Man kann also davon keinen Performance-Vorteil erwarten, sondern es handelt sich wirklich nur um eine andere Schreibweise.

Was gibt es nun noch für schöne Sachen in diesem Zusammenhang? Jeder, der schon mal mit Linq gearbeitet hat, dem ist sicherlich schon der eine oder andere LamdaExpression über den Weg gelaufen. Picken wir uns da mal einen als Beispiel raus.

IList<int> list = new List<int>();
// Liste wird irgendwie mit Werten gefüllt
IList<int> result = list.FindAll(n => n != 9);

Die FindAll Methode erwartet einen Delegate vom Typ Predicate wobei T in diesem Fall ein Integer ist durch die Liste definiert. Predicate erwartet nur einen Parameter. Daher können die Klammern um den ersten Definitions-Parameter (hier “n”) weggelassen werden.

Man kann das Ganze folgendermaßen lesen:

Überprüfe für jedes Objekt “n” in der Liste, ob “n” != 9 ist.

Ich hoffe, dass ich damit ein bisschen die Verwendung von Lamdas darstellen konnte. Natürlich setzt das in gewissem Sinne voraus, dass man allgemein mit Delegaten umgehen kann und deren Funktionsweise versteht. Wichtig ist, dass man nicht erschrickt, wenn man ein solches Konstrukt sieht, sondern eher versucht den Ursprung darin zu erkennen. Dann wird auch meistens klar, was beim jeweiligen Lamda Expression passiert.