Concise C# Part 1 : Extension methods and Linq

Because, short code is easier to understand, I decided to publish some posts about making C# code shorter. I’ll talk about small tricks I use to significantly reduce the amount of code I write to achieve my goals. Some people don’t agree with that idea because there has been abuses done by perl and c programmer in the past. I think that, if you use correct names for methods, variable and types, the shortest code will still be easy to understand.

This post is part of a serie about making C# code shorter

In this post, I’ll use the following class for my examples :

public class Post
{
    public int Id { get; set; }
    public string Author { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }
}

Linq extension methods

Linq is a set of contracts (interfaces) wich allow the developper to request objects from a data store. What make it unique is that :
– the query language is strongly typed (at compile time you are sure that all column names et types are corrects and that there are no missin semi-colon
– it supports unlimited data store type (including all database systems, xml files, google data, twitter posts, in memory objects …)

I’ll focus primarily on Linq to Objects (in memory object) because we’re talking about making code concise. So here are the shortcuts !

Searching an unique element in a collection

//Concise and Sweet
public Post GetById(int id, IList posts)
{
    return posts.FirstOrDefault(p => p.Id == id);
}

//Verbose and Ugly
public Post GetById(int id, IList posts)
{
    foreach (Post current in posts)
    {
        if (current.Id == id)
        {
            return current;
        }
    }
}

Filtering a collection

//Concise and Sweet
public IList FindByAuthor(string author, IList posts)
{
    return posts.Where(p => p.Author == author).ToList();
}

//Verbose and Ugly
public IList FindByAuthor(string author, IList posts)
{
    List result = new List();
    foreach (Post current in posts)
    {
        if (current.Author == author)
        {
            result.Add(current);
        }
    }
    return result;
}

Selecting a column (one property of an object collection)

//Concise and Sweet
public IList ExtractTitles(IList posts)
{
    return posts.Select(p => p.Title).ToList();
}

//Verbose and Ugly
public IList ExtractTitles(IList posts)
{
    List result = new List();
    foreach (Post current in posts)
    {
        result.Add(current.Title);
    }
    return result;
}

Apply changes to a collection

//Concise and Sweet
public IList Anonymize(IList posts)
{
    return posts.Select(p => new Post
    {
        Id = p.Id,
        Title = p.Title,
        Author = "***",
        Content = p.Content
    }).ToList();
}

//Verbose and Ugly
public IList Anonymize(IList posts)
{
    List result = new List();
    foreach (Post current in posts)
    {
        Post anonymousPost = new Post();
        anonymousPost.Id = current.Id;
        anonymousPost.Title = current.Title;
        anonymousPost.Author = "***";
        anonymousPost.Content = current.Content;
        result.Add(anonymousPost);
    }
    return result;
}

Creating your own extension methods

Extension methods are the best candidates when you plan to build your very own low level toolset. Here are some examples to give you an idea.

public static class MyExtensions
{
    //Index a collection by its key
    public static IDictionary IndexBy(this IEnumerable target, Func keyExtractor)
    {

        var result = new Dictionary();
        foreach (var current in target)
            result[keyExtractor(current)] = current;
        return result;
    }

    //Joining any collection of string (array, list, enumerable ...)
    public static string Join(this IEnumerable elements, string separator)
    {
        return string.Join(separator, elements.ToArray());
    }
}