Prototyping with anonymous classes


In the last post, I presented a rather strange bit of code:

public static class ExpressionExtensions
{
    public static Expression<Func<T, TResult>> Expr<T, TResult>(
        this T item,
        Expression<Func<T, TResult>> expr)
    {
        return expr;
    }
}

It looks like a rather pointless bit of code that I would write.  As Jeremy Skinner pointed out, this kind of code can help build up an expression for an anonymous type.  Anonymous types work really great, except that you can’t normally declare them as return types:

public object BuildSomething()
{
    var item = new
    {
        Foo = "foo",
        Bar = 1
    };
    return item;
}

I can only return the anonymous object as a return type.  However, that’s not always the case.  With generic inference, the entire LINQ set of extension methods is built around the idea of using anonymous types for the “T” in IEnumerable:

var item = new
{
    Foo = "foo",
    Bar = 1
};

var range = Enumerable.Repeat(item, 1);

Here, I can build an enumerable of some anonymous item, using a compiler trick (and our friend the “var” keyword) to do so.  Because the anonymous object is passed in to the Repeat method, the compiler is able to do the generic inference and determine what the anonymous type is.  But I wouldn’t be able to specify the generic arguments if I wanted to.

This technique becomes interesting when you want to do things like build lists, dictionaries, expressions and so on of anonymous types.  In many unit tests, I have to build up dummy classes representing a prototype class for something I’m interested in testing.  In the expression case, I was using expressions to test out a custom expression visitor.  Rather than building out a ton of dummy classes, I can use an anonymous type as a prototype:

[Test]
public void Some_test()
{
    var anon = new
    {
        Foo = "foo"
    };

    var expr = anon.Expr(x => x.Foo);

    var result = new CustomExpressionVisitor().Visit(expr);

    // Assert the result
    result.ShouldEqual("foo");
}

The building of my anonymous object represents a specification of the shape of what I’m asserting against.  It’s a prototype class that only exists in the context of this one method, and is then thrown away.

The trick is just to build a generic method that accepts a the item as one of its parameters – that allows the C# type inference to do its work.  It doesn’t even have to be an extension method:

[Test]
public void Some_test()
{
    var anon = new
    {
        Foo = "foo"
    };

    var expr = Expr(anon, x => x.Foo);

    var result = new CustomExpressionVisitor().Visit(expr);

    // Assert the result
    result.ShouldEqual("foo");
}

private static Expression<Func<T, TResult>> Expr<T, TResult>(
        T item,
        Expression<Func<T, TResult>> expr)
{
    return expr;
}

Imagine that I could build a List, Dictionary, etc.  Any kind of real generic method can be now called by wrapping it in an overload that takes the prototype object as an argument.

It has the tendency to obfuscate a little, but it’s a handy trick to reduce a lot of the dummy classes I wind up creating in tests.

Trivia Friday