Skip to content

2010 02 19 net 4 0 expression trees extension expressions

Fabian Schmied edited this page Feb 19, 2010 · 1 revision

Published on February 19th, 2010 at 10:57

.NET 4.0 expression trees: Extension expressions

As I mentioned in my last blog post, .NET 4.0 has introduced an extension expression model. Now, what did I mean by that, and why is it important?

Many LINQ providers define their own custom expression types that derive from the Expression base class and can be inserted into the expression tree. A SqlColumnExpression, for example, might represent a SQL column in an expression tree that is meant to be converted to SQL. A VBCompareExpression might represent a comparison with VB-specific semantics. In previous versions, the .NET framework provided little support for that; among other things, you had to use undefined ExpressionType enumeration values to represent your expressions, and including visitor support for them was a difficult thing.

With .NET 4.0, it’s now possible to define extension expressions with the following features:

  • They need not use an undefined ExpressionType value, they can use the value ExpressionType.Extension.
  • They can implement an Accept method to delegate to a specific visitor method if the visitor supports the custom expression type. If it does not, they can dispatch to a generic VisitExtension method (see below).
  • Extension expressions can also be reduced to a semantically equivalent tree of standard expression nodes, if possible. This enables high-level nodes to be compiled to IL, for example, which wouldn’t make much sense for a SqlColumnExpression, but would be handy for a ForEachExpression or a VBCompareExpression, for example.

As noted above, ExpressionVisitor now sports a VisitExtension method, which is by default invoked by the Accept methods of extension expressions. This can be used by visitors to react on extension expression types unbeknown to them.

The interesting thing about VisitExtension is its default implementation, which is to call Expression.VisitChildren. VisitChildren enables extension expressions to apply visitors to their child nodes even when those visitors do not know how to handle the specific extension expression types. In a way, this overcomes the big problem of the Visitor design pattern, where the visitors need to (statically) know about the whole type hierarchy of the objects being visited.

To understand the implications of this, consider a generic filtering visitor that replaces all ConstantExpression instances with SqlParameterExpressions. The VisitChildren approach allows the visitor to replace ConstantExpressions that are located beneath a VBCompareExpression even when it doesn’t know anything about that specific expression kind.

Here’s a picture of the visitor in action:

visitors class diagram

Without the VisitChildren approach, the visitor – because it knows nothing of VBCompareExpressions – would have no way of inspecting those ConstantExpressions.

As I said in my last post, I think .NET 4.0 expression trees do add a lot to their 3.5 counterparts, and the extension expression model is one of the most interesting new features. Because I like that concept so much, I’m going to copy it for re-linq. That way, every LINQ provider based on re-linq will be able to use extension expressions for both .NET 3.5 and .NET 4.0. And, if you haven’t guessed by now, I’ll use that model for finally implementing VB.NET support in re-linq. But more on that in a future blog post.

- Fabian

Comments

uTILLIty - February 19th, 2010 at 16:55

Hi Fabian,

thanks for digesting the enhancements for us! I’m on the user side of linq and want to get into this subject a bit further. Therefore please post some code-snippets with your blogs, which illustrate the things a bit more to us "common people" ;).

regards, uTILLIty

Fabian Schmied - February 19th, 2010 at 17:13

Thanks for the feedback!

You’re right, that blog post was targeted at "experts" already knowing a lot about LINQ expressions.

If you want to learn more about how LINQ expressions work in general, I’d refer you to the MSDN article on expression trees (msdn.microsoft.com/en-us/library/bb397951.aspx) and the re-linq white paper.

Regarding the extension expression model, I’ll show you some source code when I’ve implemented it in re-linq.

Phil - May 4th, 2010 at 15:32

How far are you of this vb.net support? Is there something for us in the source code trunk?

Thank you

Fabian Schmied - May 5th, 2010 at 10:18

Unfortunately, we haven’t been able to implement VB.NET support yet because we’re spending all of our time on a new SQL backend.

VB.NET-specific expressions are planned for after the SQL backend has been finished.

football socks - July 7th, 2010 at 11:24

Good article…I will use some of these interesting principles myself…more great info please…

Clone this wiki locally