Creating an Empty List<AnonymousType>

This post is written by guest blogger Albin Sunnanbo. He’s a great friend and source of inspiration and also one of the best developers I know. It was Albin that first introduced me to LINQ, EF Migrations and jQuery that I now use daily.

Sometimes you use Tuple<T1, T2> in C# to store results of temporary calculations, like in the following example:

var testDataValues = new int[] { 0, 1, 2 };
 
var okResults = new List<int>();
var failedArgumentsWithError = new List<Tuple<int, string>>();
foreach (var value in testDataValues)
{
    try
    {
        var result = CalculateResult(value);
        okResults.Add(result);
    }
    catch (Exception ex)
    {
        failedArgumentsWithError.Add(Tuple.Create(value, ex.Message));
    }
}
 
foreach (var failedArgumentWithError in failedArgumentsWithError)
{
    Console.WriteLine(failedArgumentWithError.Item1 + " failed with error: " +
                      failedArgumentWithError.Item2);
}

 
The Tuple<T1, T2> however is not really good for readability, the naming of Item1, Item2, etc. does not reveal the intention of the properties. When storing temporary results like this in a method there is usually better to use an anonymous type. However to declare a list of an anonymous type you need to use a little trick with yield break.

Bitten by yield return

I like the simplicity of creating enumerations with iterator blocks through yield return. Even though I regularly do it, I was bitten by a nasty bug a few weeks ago and it was entirely my own fault.

I had been working hard on my bar management system, which includes a service to book a bar stool in advance. In my initial design, a booking had to be submitted for each day. During the first user tests, the regulars complained that it was far too complicated. They wanted to book their favorite bar stool with date intervals. The solution I came up with was a helper method that created a series of bookings between two dates.

public static IEnumerable<BarStoolBooking>SubmitSeries(BarStoolBooking bookingInfo,
    DateTime firstDate, DateTime lastDate)
{
    for (DateTime date = firstDate; date < = lastDate; date = date.AddDays(1))
    {
        bookingInfo.Date = date;
        yield return bookingInfo.Submit();
    }
}

There’s a nasty bug in there. Can you spot it? I didn’t. I was bitten by it later on, when I wrote the presentation layer.

Return IEnumerable with yield return

Ever needed to return an IEnumerable<T> from a method? Did you create a List<T> instance that you populated and returned? There is a better way, with less memory footprint and better performance.

The yield return statement is one of the more mysterious, yet very useful constructs in C#. With yield return it is possible to return an IEnumerable<T> without creating a collection of any sort (no array, no list, no anything):

public static IEnumerable<int> Numbers(int max)
{
    for(int i = 0; i < max; i++) 
    {
        yield return i;
    }
}

yield return adds one item to the returned IEnumerable<T> each time it is called, but it does not end the function as a normal return would. The function ends when flow of control reaches the end of the function body.

Using yield return makes the code shorter than creating and populating e.g. a list, but that’s only part of the strength. The real power lies in the lazy evaluation.

Software Development is a Job – Coding is a Passion

I'm Anders Abel, a systems architect and developer working for Kentor in Stockholm, Sweden.

profile for Anders Abel at Stack Overflow, Q&A for professional and enthusiast programmers

The complete code for all posts is available on GitHub.

Popular Posts

Archives

Series

Powered by WordPress with the Passion for Coding theme.