Mono.Linq.Expressions 23 Jun 2010


Statue In the same vein of my little Mono.Reflection library, which complements the System.Reflection namespace with useful features such as an IL disassembler, Mono.Linq.Expressions is a small library for everyone who has to manipulate LINQ Expression Trees. The first feature I've been adding is a simple pretty printer for expression trees. It comes in handy whenever you want a textual representation of an expression tree in a language you know. For instance, let's imagine you're calling a method returning an expression:
Expression> silly = GetSillyExpression ();
And you want to quickly have a look at what it does. You may as well use a good old Console.WriteLine, but here's what it will print:
(a, b) => IIF((a > b), {var c; ... }, {var d; ... })
Yeah right. Not very useful isn't it. So let's use your internal knowledge of the DLR and print its DebugView:
.Lambda #Lambda1(
    System.Int32 $a,
    System.Int32 $b) {
    .If ($a > $b) {
        .Block(System.Int32 $c) {
            $c = $a #+ $b;
            $c #+= 42;
            $c
        }
    } .Else {
        .Block(System.Int32 $d) {
            $d = $a #- $b;
            $d #-= 42;
            $d
        }
    }
}
Better yet. But it doesn't look even remotely familiar. Here comes Mono.Linq.Expressions. Let's call Console.WriteLine once more, but in a slightly different way:
Console.WriteLine (silly.ToCSharpCode ());
And here's the output:
int (int a, int b)
{
        if (a > b)
        {
                int c;

                c = checked { a + b };
                checked { c += 42 };
                return c;
        }
        else
        {
                int d;

                d = checked { a - b };
                checked { d -= 42 };
                return d;
        }
}
Now I get it! And it's indeed plain silly. But that's not the point. If you're implementing a language on top of the DLR, or playing with the new keyword dynamic's innards, or writing a LINQ provider, you might find it useful.