Lambda Expressions: Warum ich denke daß sie schnell gegen CCD –Prinzipien verstoßen

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

DotNetKicks-DE Image
Published Donnerstag, 18. Februar 2010 13:16 von Rainer Hilmer

Kommentare

# re: Lambda Expressions: Warum ich denke daß sie schnell gegen CCD –Prinzipien verstoßen

Dienstag, 6. Juli 2010 11:23 von Peter Bucher

Zweitere Variante ist meistens besser, wenn Platz vorhanden ist.

Du kannst aber auch folgendes machen: Where((Person person) => person.Age > 10)

Gruss Peter

# re: Lambda Expressions: Warum ich denke daß sie schnell gegen CCD –Prinzipien verstoßen

Dienstag, 6. Juli 2010 11:24 von Peter Bucher

Zweitere Variante ist meistens besser, wenn Platz vorhanden ist.

Du kannst aber auch folgendes machen: Where((Person person) => person.Age > 10)

Gruss Peter

# re: Lambda Expressions: Warum ich denke daß sie schnell gegen CCD –Prinzipien verstoßen

Dienstag, 6. Juli 2010 11:34 von Rainer Hilmer

Na das ist doch klar lesbar! Danke Peter

Kommentar abgeben

(verpflichtend) 
(verpflichtend) 
(optional)
(verpflichtend)