Debugging Expression Trees in Visual Studio 2010

Debugging Expression Trees in Visual Studio 2010

  • Comments 24

First of all, let’s take a look at the example from one of my previous posts. It creates an expression tree for calculating the factorial of a number.

ParameterExpression value = 
    Expression.Parameter(typeof(int), "value");
ParameterExpression result = 
    Expression.Parameter(typeof(int), "result");
LabelTarget label = Expression.Label(typeof(int));
BlockExpression block = Expression.Block(
    new[] { result },
    Expression.Assign(result, Expression.Constant(1)),
    Expression.Loop(
        Expression.IfThenElse(
            Expression.GreaterThan(value, 
                Expression.Constant(1)),
            Expression.MultiplyAssign(result,
                Expression.PostDecrementAssign(value)),
        Expression.Break(label, result)
        ),
        label
    )
);
Expression<Func<int, int>> lambda = 
    Expression.Lambda<Func<int, int>>(block, value);
Console.WriteLine(lambda.Compile()(5));

Now, what if you want to see the content of this tree in debug mode? You can try lambda.ToString() but it’s not very informative. All you get is this: value => {var result; … }. Basically, it tells you only that the lambda has the result parameter.

Another option is to explore the tree structure in the Watch window. However, since this is a tree, you need to click through numerous nodes. This gives you a good understanding of the tree structure, but it might be hard to understand the actual content of the tree.

But there is a better solution: expression trees now have their own visualizer that helps you to explore their structure and content.

Copy the above code example into Visual Studio 2010, set a breakpoint at the last line, and press F5. Rest the mouse pointer over the lambda variable and you will see that it has the DebugView property. This property is private and is exposed only in the debugger, so you can’t use it in your code. But it’s used to hook up the expression trees visualizer. Click the magnifying glass icon and you will see the list of available visualizers.

image

Now click Text Visualizer and you get this.

image

As you can see, the content of the expression tree is represented in some kind of metalanguage. (No, we couldn't use C# here, because expression trees serve other languages as well.)

There are some simple rules used in this metalanguage:

  • Parameters are displayed with a $ symbol at the beginning (for example, $result and $value.)
  • Integer, string, and null constants are displayed “as is” (for example, $result = 1). For other numeric types that have standard suffixes, the suffix is added to the value. (For example, for decimal the value is 1M, for double 1D, etc.)
  • If a parameter, label, or lambda expression does not have a name, the name is generated automatically (for example, #Label1, $var1, etc.)
  • Checked operators are displayed with the # symbol preceding the operator. For example, the checked addition operator is displayed as #+.

There are some other nuances that I think are evident and don't need additional explanation. But if you don’t understand something in this syntax, let me know and I'll include more information in the documentation.

Update:

Documentation for this feature is now availabe on MSDN: Debugging Expression Trees.

Leave a Comment
  • Please add 2 and 2 and type the answer here:
  • Post
  • Very nice.

    Will it get debug-step-through-support too? I.e. so when evaluating a tree one can set breakpoints, step through expressions, check values etc?

  • Why didn't you use instead of yet another meta language the relevant language that the dev is using at the time, e.g. C#, VB, etc? So that we have to remember yet another soup of symbols, rules and names?

  • NT, you don't have to use any of the new features of .NET4, they're just extras if you want them, and can find a use for them. Anyway, whilst it might technically be possible to do this sort of thing in vanilla C# or VB, it is horribly fiddly and inconvenient.

    Also, I don't see any new symbols to be learned, the rules are the same rules for any language (since pretty much all languages are underpinned by compiler that understands some sort of expression tree), and as for the names.... how else are you supposed to program anything without some sort of name to identify the constructs that you are using?

  • So this isn't strictly a new Visual Studio visualizer, but a new "debug string" available as a private property on Expression or LambdaExpression?

  • Am I right in saying this isn't available in VS2010beta2? I've just tried it and failed to get the debug view to come up... is there anything I need to do to turn this on, or is it just not in beta 2?

  • I see that the ExpressionTreeVisualizer sample is no longer shipped with VS2010, and all Expression types have a DebuggerProxyTypeAttribute. Is there a way to make VS debugger visualizer target types that have DebuggerProxyTypeAttribute applied? Textual DebugView sure is nice, but people have written much more useful visualizers and I see no obvious way to make them work with 4.0 expression types.

  • I look at that code and I want to puke.

    Now I can't wait to leave an intern in front of pages and pages of this fine new microsoft sponsored mini-programming-language-in-a-language until he blows it's brains out.

  • @Krypto: No one is forcing you or your intern to use it. Besides, it's already easier to read than the original code, and definitely easier to debug than the old way. And if your intern can't even learn to read something as simple as that example, maybe it's a good thing he's not being paid in the first place. And let's be realistic here... pages? C'mon. The author explained the whole thing in 4 bullet points.

    Anyway, moving on... this looks great! I'm glad you chose to use something that at least resembles a programming language instead of XML.

  • I am unable to see the debugview property using VS2010Beta2...

  • This feature did ship in Beta2 and I made all the screenshots using the official build. The QA team is investigating.

    If you have any problems with the feature, please let us know and give us some details. At least answer these two questions:

    1) Can you see the "DebugView" property on the Expression Tree node in the debugger?

    2) If yes, can you see the list of visualizers? 

  • Doh! I worked it out in the end... it has to be a project targeting .NET 4.0. It's not just a feature of VS2010, but also of the framework...

    Sorry for the false alarm.

    Jon

  • @ KristoferA

    I am not sure I understand your question. You can use breakpoints and see the content of the expression tree in VS2008 and in VS2010 in the same way as for any other object.

    @Pete

    Well, there is a feature in Vusual Studio that is called "visualizer". The private property "DebugView" is just used to hook up to this feature.

    @Janusz Nykiel

    Yes, this sample has not shipped with Visual Studio Beta2.

    I wonder what "other visualizers" you are referring to. Can you please provide examples? By the way, the old expression trees API has not changed, so those visualizers should work. How to support the new ET nodes is a different question, though.

  • @Alexandra Rusina

    >I wonder what "other visualizers" you are referring to. Can you please provide examples?

    The example one that shipped with VS 2008 (ExpressionTreeVisualizer), or Manuel Abadia's one (google manuel abadia visualizer). Basically, any one targeting the Expression type.

    >the old expression trees API has not changed, so those visualizers should work

    They may be source-code level compatible, but I see no way to integrate them with VS debugger, unless there is a way to have VS pick up a visualizer for a type attributed with DebuggerTypeProxy.

  • @ Janusz

    OK, I'll take a look at this problem. It might take me sometime, so don't expect a quick answer. I'll post a comment here as soon as I have something to tell you.

  • On the ExpressionTreeVisualizer question, if you read the directions on how to install/use this visualizer, you can get the visualizer working with dev10, although we haven't done this since Beta1 since we this visualizer didn't add much value over the debugview property and doesn't support any of the new nodes.

Page 1 of 2 (24 items) 12