Expression Trees in C# 3.0

Posted by: Granville Barnett, on 24 Apr 2007 | View original | Bookmarked: 0 time(s)

Out of everything in C# 3.0 this is the feature that intreges me the most - from what I have looked at this feature seems immensly powerful, LINQ to SQL takes an expression tree and uses that to generate the appropriate SQL code.

The thing I really like about expression trees is the ability to dig into them as an in-memory data structure.

In the code shown I extract parameters (types, names), expression types, and expressions.

Take a look at the below code and inspect it, run it etc...

using System;
using System.Linq;
using System.Linq.Expressions;
using System.Collections.ObjectModel;

namespace ExpressionTrees
{
    public class Program
    {
        public static void Main()
        {
            Expression<Func<int, int, int>> square = (x, y) => x * y; // in mem tree represenation of func
            ReadOnlyCollection<ParameterExpression> args = square.Parameters;
            Console.WriteLine("Expression: {0}", square.Body);  // expr of function
            foreach (ParameterExpression param in args)
            {
                Console.WriteLine("Param Name: {0} Type: {1}", param.Name, param.Type); // print out each arg and type
            }
            Func<int, int, int> squareCompiled = square.Compile(); // com
            Console.WriteLine(squareCompiled(4, 4));
            // constructing the square function using a binary expr
            BinaryExpression be = BinaryExpression.MakeBinary(ExpressionType.Multiply,
                Expression.Parameter(typeof(int), "x"), Expression.Parameter(typeof(int), "y"));
            Console.WriteLine(be.NodeType); // expr type
            Console.WriteLine("Param Name: {0} Type: {1}", be.Left, be.Left.Type);
            Console.WriteLine("Param Name: {0} Type: {1}", be.Right, be.Right.Type);

        }
    }
}
C# compiler generated code:
public class Program
{
    // Methods
    public static void Main()
    {
        ParameterExpression CS$0$0000;
        ParameterExpression CS$0$0001;
        Expression<Func<int, int, int>> square = Expression.Lambda<Func<int, int, int>>
		(Expression.Multiply(CS$0$0000 = Expression.Parameter(typeof(int), "x"),
		CS$0$0001 = Expression.Parameter(typeof(int), "y")), new ParameterExpression[]
		{ CS$0$0000, CS$0$0001 });
        ReadOnlyCollection<ParameterExpression> args = square.Parameters;
        Console.WriteLine("Expression: {0}", square.Body);
        foreach (ParameterExpression param in args)
        {
            Console.WriteLine("Param Name: {0} Type: {1}", param.Name, param.Type);
        }
        Console.WriteLine(square.Compile()(4, 4));
        BinaryExpression be = Expression.MakeBinary(ExpressionType.Multiply,
		Expression.Parameter(typeof(int), "x"), Expression.Parameter(typeof(int), "y"));
        Console.WriteLine(be.NodeType);
        Console.WriteLine("Param Name: {0} Type: {1}", be.Left, be.Left.Type);
        Console.WriteLine("Param Name: {0} Type: {1}", be.Right, be.Right.Type);
    }
}
MSIL (only local variables):
.locals init (
	[0] class [System.Core]System.Linq.Expressions.Expression'1<class
	[System.Core]System.Linq.Func'3<int32, int32, int32>> square,
	[1] class [mscorlib]System.Collections.ObjectModel.ReadOnlyCollection'1<class
	[System.Core]System.Linq.Expressions.ParameterExpression> args,
	[2] class [System.Core]System.Linq.Expressions.ParameterExpression param,
	[3] class [System.Core]System.Linq.Func'3<int32, int32, int32> squareCompiled,
	[4] class [System.Core]System.Linq.Expressions.BinaryExpression be,
	[5] class [System.Core]System.Linq.Expressions.ParameterExpression CS$0$0000,
	[6] class [System.Core]System.Linq.Expressions.ParameterExpression CS$0$0001,
	[7] class [System.Core]System.Linq.Expressions.ParameterExpression[] CS$0$0002,
	[8] class [mscorlib]System.Collections.Generic.IEnumerator'1<class
	[System.Core]System.Linq.Expressions.ParameterExpression> CS$5$0003,
	[9] bool CS$4$0004)
Enjoy.

Advertisement
Free Agile Project Management Tool from Telerik
TeamPulse Community Edition helps your team effectively capture requirements, manage project plans, assign and track work, and most importantly, be continually connected with each other.
Category: Regex | Other Posts: View all posts by this blogger | Report as irrelevant | View bloggers stats | Views: 2760 | Hits: 30

Similar Posts

  • ASP.NET MVC: Expression Trees as Parameter to Simplify Query more
  • How can I get objects and property values from expression trees? more
  • Getting Information About Objects, Types, and Members with Expression Trees more
  • Debugging Expression Trees in Visual Studio 2010 more
  • More Fun with Regular Expressions : Word and Paragraph Parsing more
  • Lookbehind in Regex searches more
  • Filtering with string parameter that allows free user input more
  • Generating Dynamic Methods with Expression Trees in Visual Studio 2010 more
  • querySelectorAll on old IE versions: something that doesnt work more
  • LINQ Tip of the week: System.String support more

News Categories

.NET | Agile | Ajax | Architecture | ASP.NET | BizTalk | C# | Certification | Data | DataGrid | DataSet | Debugger | DotNetNuke | Events | GridView | IIS | Indigo | JavaScript | Mobile | Mono | Patterns and Practices | Performance | Podcast | Refactor | Regex | Security | Sharepoint | Silverlight | Smart Client Applications | Software | SQL | VB.NET | Visual Studio | W3 | WCF | WinFx | WPF | WSE | XAML | XLinq | XML | XSD