Just taking a quick break from proof-reading to post a thought I had yesterday. Visual LINQ uses
ToString() to convert an expression tree’s body into readable text. In some cases it works brilliantly, reproducing the original source code exactly – but in other cases it’s far from useful. For instance, from this expression tree representation:
I suspect you wouldn’t have guessed that the original code was:
Personally I don’t find it terrifically obvious, even though I can see how it works. Here’s a thought though – suppose the
LambdaExpression class had a
Source property which the compiler could optionally provide as a constructor argument, so that you could get at the original source code if you needed it. The use in Visual LINQ is obvious, but would it be useful elsewhere?
Well, suppose that LINQ to SQL couldn’t translate a particular query expression into SQL. Wouldn’t it be nice if it could report the part of the query expression it was having trouble with in the language it was originally written in? So a VB expression would give source in VB, a C# expression would give source in C# etc.
All of this would have to be optional, and I suspect some people would have intellectual property concerns about their source leaking out (most of which would be silly, due to the logic effectively being available with a call to
ToString() anyway). I think it would be quite handy in a few situations though.
5 thoughts on “LambdaExpression – source code would be nice”
The problem is that the first line is a VB.NET representation and the second is in C#.
No, the first is the expression tree representation – if you look at what’s in the generated IL, that’s basically it. I’d hope to see the letter ‘q’ in any sensible VB.NET code.
Just because it uses a single = doesn’t mean it’s valid VB :)
(In addition, the Convert method needs a type parameter to say what type to convert it to… this is an expression tree convert.)
Expression tree representations give a curious mixture of C# and VB syntax. For instance, consider this:
Expression<Func> func = word => word==”hello” ? “yes” : “no”;
Now display func.ToString():
word => IIF((word = “hello”), “yes”, “no”)
The => bit looks like C#, but the IIF bit looks like VB. In fact, it’s not the same as VB, because in VB, IIF will evaluate *all* the expressions. Expression.ConditionalExpression acts like the conditional operator in C# – it doesn’t evaluate more than it has to.
So in other words, it’s currently a bit of a mess if you push it hard enough :)
Don’t you mean:
(Convert(word.get_Chars(0)) == 113)
Nick: No, I don’t. That’s the output of expression.Body.ToString().
You don’t need to go that far to see the single equals, either. For instance:
number => number==10
is displayed as:
number => (number = 10)
I just stumbled upon your post. You might find helpful the following post that makes the source code from expression trees. I also used one of your comments in the sample.