Oft wird mir etwas unwohl wenn ich eine Lambda expression sehe. Lange Zeit wußte ich nur vage warum überhaupt. Sie lassen sich schlecht lesen, aber warum? Jetzt ist bei mir der Groschen gefallen. Es sind die anonymen Parameter. Hier ein Beispiel:
/// <summary>
/// Create a Lookup to organize the packages.
/// Use the first character of Company as the key value.
/// Select Company appended to TrackingNumber for each element value in the Lookup.
/// </summary>
/// <param name="packages">The packages to put into the lookup tale.</param>
/// <returns>A lookup tale containing the packages.</returns>
private static Lookup<char, string> CreateLookup(IEnumerable<Package> packages)
{
return (Lookup<char, string>) packages.ToLookup(
p => Convert.ToChar(p.Company.Substring(0, 1)),
p => p.Company + " " + p.TrackingNumber);
}
Jetzt der gleiche Code mit anonymen Methoden:
private static Lookup<char, string> CreateLookup(IEnumerable<Package> packages)
{
return (Lookup<char, string>) packages.ToLookup(
delegate(Package p) { return Convert.ToChar(p.Company.Substring(0, 1)); },
delegate(Package p) { return p.Company + " " + p.TrackingNumber; });
}
Definierte Parameter
Hier wird sofort ersichtlich daß
p vom Typ
Package ist; das erhöht die Lesbarkeit deutlich (
CCD). Die Typinformation geht bei einer Lambda Expression flöten und zumindest ich muß mir den Typ erst gedanklich herleiten.
Definierter Return
Hat man es mit einer komplexeren Lambda expression zu tun, kann es sogar passieren daß nicht mehr gleich ersichtlich ist, was diese überhaupt zurück gibt (
CCD)!
Lesbarkeit, SRP, Testbarkeit
Das gilt umso mehr, wenn man auch noch mehrere Lambda Expressions ineinander verschachtelt. Was ich sowieso als großes NO GO ansehe, weil es nicht nur die Lesbarkeit drastisch mindert, sondern obendrein auch noch das
SRP verletzt und die Testbarkeit verschlechtert. Ein Beispiel dafür kann man in meinem Artikel
http://dotnet-forum.de/blogs/rainerhilmer/archive/2009/10/30/linq-lambda-and-testability-issues.aspx sehen. Wie man so ein Knäuel auflöst und besser testbar macht, erläutern die Folgeartikel
http://dotnet-forum.de/blogs/rainerhilmer/archive/2009/10/30/testing-a-dismantled-linq-expression.aspx
http://dotnet-forum.de/blogs/rainerhilmer/archive/2009/10/30/stripping-down-a-convoluted-linq-expression.aspx
Ich muß gestehen daß Lambda expressions sexier aussehen als anonyme Methoden (was für Geeks wir sind). Wie wäre es mit folgender Alternative:
private static Lookup<char, string> CreateLookup(IEnumerable<Package> packages)
{
return (Lookup<char, string>) packages.ToLookup(
package => Convert.ToChar(package.Company.Substring(0, 1)),
package => package.Company + " " + package.TrackingNumber);
}
Statt einem kryptischen, nichtssagenden Buchstaben steht jetzt dort ein Parametername mit Aussage. Das ist doch was.
Happy Coding