Im ersten und zweiten Teil dieser Serie ging es um Automated Properties, Object Initializer, Collection Initializer und Extension Methods. Dieser dritte Teil widmet sich den Lambda Expressions.
Lambda Expressions gehören zu den syntaktisch anfänglich etwas weniger eingängigen neuen Sprachkonstrukten in C# 3.0. (Hinweis für VBler: In der aktuellen "Orcas" Beta stehen Lambda Expressions für VB noch nicht zur Verfügung, VB wird sie allerdings unterstützen.)
In diesem Beitrag betrachten wir lediglich die grundsätzliche Struktur von Lambda Expressions; in einem späteren Beitrag werde ich ausführlich auf Expression Trees eingehen, die eng mit dem Konzept von Lambda Expressions zusammen hängen.
Betrachten wir zum Einstieg das folgende C#-Fragment:
code
1 delegate int SimpleDelegate(int i);
2
3 static void Main(string[] args)
4 {
5 SimpleDelegate sd = new SimpleDelegate(SimpleMethod);
6 Execute(sd);
7 }
8
9 private static void Execute(SimpleDelegate d)
10 {
11 Console.WriteLine(d(5));
12 Console.ReadLine();
13 }
14
15 private static int SimpleMethod (int i)
16 {
17 return i * 2;
18 }
Bevor wir Lambda Expressions nutzen um dieses zugegeben ziemlich nutzlose Beispiel eleganter zu codieren, vereinfachen wir es zunächst durch die seit C# 2.0 zur Verfügung stehenden anonymen Methoden:
code
1 class Program
2 {
3 delegate int SimpleDelegate(int i);
4
5 static void Main(string[] args)
6 {
7 SimpleDelegate sd =
8 delegate(int i) { return i * 2; };
9 Execute(sd);
10 }
11
12 private static void Execute(SimpleDelegate d)
13 {
14 Console.WriteLine(d(5));
15 Console.ReadLine();
16 }
17 }
Im Grunde haben wir eine anonyme Methode dazu verwendet, SimpleMethod() inline zu definieren (Zeile 8).
Mit einer Lambda Expression können wir den Code weiter zusammenfassen und zwar in dem wir diese Zeile
code
delegate(int i) { return i * 2; };
durch diese
code
(int i) => { return i * 2; };
ersetzen. Das delegate Keyword wurde also durch die neue Lambda Expression Syntax => ersetzt. Der eigentliche Vorteil von Lambda Expressions ist jedoch, dass man den Ausdruck weiter vereinfachen kann, insofern die Methode nur einen einzigen return Wert liefert. Gleichzeitig kann man es dem Compiler überlassen, den Parameter-Typ per Reflection zu erkennen:
code
SimpleDelegate sd = i=>i * 2;
Aus ursprünglich 8 Zeilen ist so ein Einzeiler geworden!
Es mag eingefleischten .NET Entwicklern etwas mulmig werden, ob der fehlenden Typ-Definition für i in obigem Ausdruck. Es ist jedoch wichtig zu verstehen, dass die Typsicherheit von C# nicht aufgeweicht wird, oder gar verloren geht. Der C# Compiler kann in obiger Lambda Expression den Typ von i vollständig auflösen, da der Typ des Ausdrucks i * 2 eindeutig ist. Visual Studio 2008 zeigt in logischer Konsequenz diesen natürlich auch entsprechend an:
Lambda Expressions sind nicht auf Methoden mit einem einzelnen Parameter beschränkt:
code
SimpleDelegate sd = (a, b) => a * b;
Übrigens: Der C# Compiler übersetzt Lambda Expressions in equivalente Delegates und Hilfsmethoden wie im Codebeispiel am Anfang dieses Beitrages, d.h. das Assemblies in denen Lambda Expressions genutzt werden, auch weiterhin auf der CLR 2.0 lauffähig sind. Lambda Expressions sind eine Spracherweiterung, keine Erweiterung der Common Language Runtime!