Expression trees’ ConstantExpression values

After reading Jafar Husain‘s posts (1, 2 and bonus by Doron Yaacoby), I started thinking about being able to strong type names using the Expression classes.

One of the things I came up with is creating a tracing framework where Expression is passed, instead of strings or other untyped methods.

[Conditional("DEBUG")]
public static void TraceStart<T, R>(
this T me, Expression<Func<T, R>> where) {
// ...
}

[Conditional("DEBUG")]
public static void TraceEnd<T, R>(
this T me, Expression<Func<T, R>> where, R returnValue) {
// ...
}

class Foo
{
public bool Bar(int param)
{
this.TraceStart(o => o.Bar(param));

this.TraceEnd(o => o.Bar(param), false);

return false;
}
}

Since the TraceStart and TraceEnd methods are decorated with a ConditionalAttribute, the Expression objects will not even be created (since the calls will not be made).

Nice idea, but the overhead during debugging might just be too much.

 

Here’s where the interesting bit comes in: While I was fiddling with the idea, I tried to print the value of param, by reaching the expression tree’s ConstantExpression for it. However, the type in the expression’s Value property was of a type named: Namespace.Foo+<>c__DisplayClass0.

OK, so where do I get the value from? Apparently, Namespace.Foo+<>c__DisplayClass0 has a public field named value. That’s where. Oh, but wait. You can’t get it – since it’s a field, you can’t get it using polymorphism, but even if it was a property, Namespace.Foo+<>c__DisplayClass0 doesn’t inherit or implement anything.

Resorting to reflection seems like a terrible solution. I just hope that this will change until C# 3.0 RTMs.

Advertisements

2 thoughts on “Expression trees’ ConstantExpression values

  1. c__DisplayClass0 is the result of creating a closure, which is required for your lambda expressions since they reference param. I don’t see a way that you will be able to pull that value out without reflection. What you could do is cache the FieldInfo object you get back. Alternatively, you could pass all the params as params object[], duplicating the argument list. If I had to do this often, I’d try to use Aspect Oriented Programming (AOP) to insert your tracing code. I wouldn’t relish the thought of having to insert trace statements a lot of places when AOP was invented to do just that. AOP could also take care of handling multiple returns.

  2. All I’m saying is that it’s a shame that the generated type didn’t have a base class of ValueHolder(Of T) or something that I could use… :/
    And it’s ok, this is purely for academic purposes. :)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s