Sorting a .Net list with lambdas

I love linq.  I would wager that most developers who have done much with it share a similar love.

It makes our lives easier.  It eliminates writing copies amounts of loops, parsing xml, interacting with databases, you name it.  It’s great.

When I run into a situation where linq does not have an obvious tie in, I start to get a little anxious,  (pathetic I realize).

Today I was faced with a situation where I had a list of custom classes that I needed to sort.

This being a list, OrderBy was nowhere to be found.

So, I returned to my roots and started writing a compare for my class so that I could use the Sort command that *is *part of the List generic type.  That is when it struck me that I could probably accomplish this using a lambda.  It turns out that I was correct.  Lambda’s were a perfect fit for this scenario.  The code remained clean and concise and I was saved having to write additional methods just to accomplish a one-off scenario on what was a otherwise complete project.

Lamdas are a progression in C# past anonymous methods.  In the code below, I show how the code would be implemented with separate function, an anonymous method and finally, with a Lambda expression.

First, the test class that we’ll be working with:

public class MyClass { 
     public int propA { get; set; } 
     public int propB { get; set; } 
     public int propC { get; set; } 
}

Our test class:

public class Tester { 
     public void Main() { 
          List list = new List(); 
          list.Add(new MyClass() { propA = 1, propB = 2, propC = 3 }); 
          list.Add(new MyClass() { propA = 2, propB = 3, propC = 4 }); 
          list.Add(new MyClass() { propA = 3, propB = 4, propC = 5 }); 
          list.Add(new MyClass() { propA = 4, propB = 5, propC = 6 }); 
     }
}

Now then, we write a custom comparer.  Not a lot of code, but you can imagine how this extrapolates over various properties for large classes.

public class Tester { 
    private static int CompareByPropA(MyClass a, MyClass b) { 
        return a.propA.CompareTo(b.propA); 
    } 
    public void Main() { 
        List list = new List(); 
        list.Add(new MyClass() { propA = 1, propB = 2, propC = 3 }); 
        list.Add(new MyClass() { propA = 2, propB = 3, propC = 4 }); 
        list.Add(new MyClass() { propA = 3, propB = 4, propC = 5 }); 
        list.Add(new MyClass() { propA = 4, propB = 5, propC = 6 }); 
        //Using the comparer built into the MyClass method
        list.Sort(CompareByPropA); 
    } 
}

This time, we drop the custom comparer and implement the sort using an anonymous method.

public class Tester { 
    public void Main() { 
        List list = new List(); 
        list.Add(new MyClass() { propA = 1, propB = 2, propC = 3 }); 
        list.Add(new MyClass() { propA = 2, propB = 3, propC = 4 }); 
        list.Add(new MyClass() { propA = 3, propB = 4, propC = 5 }); 
        list.Add(new MyClass() { propA = 4, propB = 5, propC = 6 }); 
        //Using an anonymous method 
        list.Sort(delegate(MyClass a, MyClass b) { 
             return a.propA.CompareTo(b.propA); }); 
    } 
}

Finally, we rewrite the anonymous method into a Lambda.  It is still easy to read and much more concise.

public class Tester { 
    public void Main() { 
        List list = new List(); 
        list.Add(new MyClass() { propA = 1, propB = 2, propC = 3 }); 
        list.Add(new MyClass() { propA = 2, propB = 3, propC = 4 }); 
        list.Add(new MyClass() { propA = 3, propB = 4, propC = 5 }); 
        list.Add(new MyClass() { propA = 4, propB = 5, propC = 6 }); 
        //Using a Lambda 
        list.Sort((a, b) => a.propA.CompareTo(b.propA)); 
    } 
}

So, next time you go to write custom compare code, step back and see if you can do it a little more simply.  If you are going to be using your comparison code in more than one place, then perhaps it is still a better idea to implement it using that route vs the lambda.  If it is a one-off thing, then a lambda and some linq can be a beautiful thing!