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.

With the following extension method:

public static class CollectionEx
{
    /// <summary>
    /// Returns an empty IEnumerable<T>.
    /// </summary>
    /// <typeparam name="T">The type of the items in the collection</typeparam>
    /// <param name="item">An example of the item, this item is never used</param>
    /// <returns>IEnumerable<T> with 0 items</returns>
    public static IEnumerable<T> YieldEmpty<T>(this T item)
    {
        yield break;
    }
}

Now we can rewrite the above example with an anonymous type

var testDataValues = new int[] { 0, 1, 2 };
 
var okResults = new List<int>();
// Initialize with an example-item with members of correct name and type. 
var failedArgumentsWithError = 
    new { Argument = 0, ErrorMessage = string.Empty }.YieldEmpty().ToList();
foreach (var value in testDataValues)
{
    try
    {
        var result = CalculateResult(value);
        okResults.Add(result);
    }
    catch (Exception ex)
    {
        failedArgumentsWithError.Add(
            new { Argument = value, ErrorMessage = ex.Message });
    }
}
 
foreach (var failedArgumentWithError in failedArgumentsWithError)
{
    Console.WriteLine(failedArgumentWithError.Argument + " failed with error: " +
                      failedArgumentWithError.ErrorMessage);
}

The content of the CalculateResult method is not really relevant, but here is an example if you want to get some output of the examples above.

private static int CalculateResult(int value)
{
    checked
    {
        var tempresult = 1 / value;
        var result = int.MaxValue * value;
        return result;
    }
}

1 comment

  1. Pretty good. Working as expected.
    I was not aware of the yield break keywords.

    Thanks!

Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.