Writing your own filters with LINQ

I recently read an article by Mark Needham on how we tend to duplicate LINQ filters in our code.  He makes a good point – for example, you might see the following code in your application.

users.Single(u => u.Id == id)

While this is a pretty simple line of code we might end up duplicating this filter in a number of places.  In his example he uses a simple property to avoid the duplication – I usually write my own filters.

public static class UserFilters
{
    public static User WithId(this IQueryable<User> users, int id)
    {
        return users.Single(u => u.Id == id);
    }
}

The original code now also becomes much more readable.

users.WithId(id)

Another bonus here is that we can write unit tests for our filters!

[Test]
public void ShouldFilterUsersBySpecifiedAge()
{
    SystemTime.Now = () => new DateTime(2020,1,1);

    var users = new List<User>();
    users.Add(new User { Birthdate = new DateTime(2010,1,1) });
    users.Add(new User { Birthdate = new DateTime(2005,1,1) });
    users.Add(new User { Birthdate = new DateTime(2000,1,1) });
    users.Add(new User { Birthdate = new DateTime(1995,1,1) });

    Assert.AreEqual(2, users.AsQueryable().OlderThan(18).Count());
}

Less duplication, improved readability and testability.  This trick is especially useful if you are using complex filters.  If you’re wondering about my use of SystemTime – this is a trick I learnt from Ayende Rahien.

Happy coding.