Editorials

LINQ and Lambda Expressions Communication Intentions

LINQ and Lambda Expressions Communication Intentions
In a procedural language you can easily write code without Lambda Expressions and LINQ using a “for” or “foreach” structure. Performance is generally not an issue, and if you know how to write LINQ queries to utilize the underlying engine you may find as good or even better performance.

So, why would you use one over the other? Let’s consider coding a requirement to sum all the count properties in a set of objects stored in a collection. We will write the code in both a foreach lop and a LINQ query using a lambda expression for comparison.

Here is the code for our example comparison. The example is in C#.

internal class MyObject

{

public int Count { set; get; }

}

public static class Program

{

private static void PrintSumUsingForEach(IDictionary<string, MyObject> myList)

{

int total = 0;

foreach (var myObject in myList.Values)

{

if (myObject != null) total += myObject.Count;

}

Console.WriteLine("Sum of the Count in all myObject instances is {0}", total);

}


private static void PrintSumUsingLinq (IDictionary<string, MyObject> myList)

{

int total = myList.Values.Where(p => p != null).Sum(p => p.Count);

Console.WriteLine("Sum of the Count in all myObject instances is {0}", total);

}


public static void Demo()

{

IDictionary<string, MyObject> myList = new Dictionary<string, MyObject>();

myList.Add("Item1", new MyObject { Count = 1 });

myList.Add("Item2", new MyObject { Count = 2 });

myList.Add("Item3", new MyObject { Count = 3 });

myList.Add("Item4", null);


PrintSumUsingForEach(myList);

PrintSumUsingLinq (myList);

}

}

Here is a short description of what I have done in the example above:

  1. I create a class object “MyObject” having a single property, Count.
  2. I have two functions defined to calculate the total of the count property from a collection of MyOjbects, and print the results to the console.
    1. PrintSumUsingForEach uses the “foreach” technique to get the totals.
    2. PrintSumUsingLinq uses a LINQ expression to calculate the total.
  3. I have a function Demo.
    Demo creates a dictionary and populates it with 4 entries. To make things more interesting, the fourth entry has a null value where an instance of MyObject is left out.

Running the demo method results in the output :

Sum of the Count in all myObject instances is 6

Sum of the Count in all myObject instances is 6

As you can see, both methods work exactly the same. So why would you prefer one over the other if performance isn’t an issue, and the output is identical?

As I understand it, the LINQ expression is more descriptive of the intention of the developer. In the “foreach” method you have an if statement testing if myObject is null followed by the incrementing of total by the amount in the myObject.Count property if it isn’t null. However, you have to infer that is the intention of the code by reading the syntax.

The LINQ query, on the other hand, tells you what the intention of the developer was with the use of verbs. Starting with the list we use a “Where” operation. The Where operation requires you to provide a filtering criteria provided with a Lambda expression of p => p!=null. The variable p is replaced with every instance of myObject found in the list MyList.Values.

Now that we have filtered our list to only those having an instantiated MyObject, we can apply the Sum operation. The Sum operation using the Lambda expression p=>p.Count returning the Count property of every p. Like the Where operation, p is again replaced with every instance of MyObject in the list produced by the Where filter. Because the Where filter removed all null MyObject instances, no null exceptions were thrown when computing the sum of the counts.

So, it is the existence of the Where and Sum operators in the LINQ query that make it more expressive, telling other developers what was the intention of the code. You don’t have to derive the intent by the contents of commands contained in the for loop.

What do you think? Is this syntactical KoolAid? Is one really better than the other? Include your opinion here, or drop an Email to btaylor@sswug.org with your thoughts on the matter.

Cheers,

Ben