<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>{(something&#124;&#124;other).soft()} &#187; expressions</title>
	<atom:link href="http://www.somethingorothersoft.com/tag/expressions/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.somethingorothersoft.com</link>
	<description>About Software Development And Other Stuff By Igor Zevaka</description>
	<lastBuildDate>Mon, 25 Jul 2011 00:03:47 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Converting an Expression to a compiled Lambda</title>
		<link>http://www.somethingorothersoft.com/2010/06/18/converting-an-expression-to-a-compiled-lambda/</link>
		<comments>http://www.somethingorothersoft.com/2010/06/18/converting-an-expression-to-a-compiled-lambda/#comments</comments>
		<pubDate>Thu, 17 Jun 2010 23:45:08 +0000</pubDate>
		<dc:creator>igor</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[csharp]]></category>
		<category><![CDATA[expressions]]></category>
		<category><![CDATA[lamdbas]]></category>

		<guid isPermaLink="false">http://www.somethingorothersoft.com/?p=398</guid>
		<description><![CDATA[A quick guide on how to convert an expression to a compiled lambda.]]></description>
			<content:encoded><![CDATA[<h3>Compiling an expression to a lambda</h3>

<p>Today I had to convert a binary expression to a lambda and then use in a where clause on a collection. Easy enough, I thought, make an <code>ExpressionLambda</code>, compile it, substitute it into the where clause, no worries.</p>

<p>This is the first cut of the code:</p>

<div>
<pre class="brush: csharp; title: ; notranslate">

public class ClassWithProperties {
    public string Prop { get; set; }
}

static void ExpressionCrashes() {

    var expr = Expression.Equal(Expression.Property(Expression.Variable(typeof(ClassWithProperties)), &quot;Prop&quot;), Expression.Constant(&quot;value2&quot;));

    var props = new[] { Expression.Parameter(typeof(ClassWithProperties)) };
    //Throws &lt;variable '' of type 'SOCSTest.ClassWithProperties' referenced from scope '', but it is not defined&gt;
    var lambda = Expression.Lambda&lt;Func&lt;ClassWithProperties, bool&gt;&gt;(expr, props).Compile();

    var items = new List&lt;ClassWithProperties&gt; { 
        new ClassWithProperties{Prop = &quot;value1&quot;},
        new ClassWithProperties{Prop = &quot;value2&quot;},
        new ClassWithProperties{Prop = &quot;value2&quot;}
    };

    //Should return &lt;&quot;value2&quot;, &quot;value2&quot;&gt;
    items.Where(lambda);
}

</pre>
</div>

<p>The expression is a basic one &#8211; it calls an equality comparison on a property off an object and a constant. It is equivalent to this:</p>

<div>
<pre class="brush: csharp; title: ; notranslate">
value.Prop == &quot;value2&quot;
//Where value is a parameter of type ClassWithProperties
</pre>
</div>

<p>Googling for this exception and just general expression and lambda stuff kinda hints at people having the same problem as I am but with no fast solution. It was Jon Skeet&#8217;s <a href="http://stackoverflow.com/questions/1574427/lambda-parameter-not-in-scope-while-building-binary-lambda-expression/1574455#1574455">answer to question I didn&#8217;t understand</a> on StackOverflow that finally put me onto the right track.</p>

<p>In order to compile a lambda from an expression, you need to provide <strong>all instances of <code>ParameterExpression</code></strong> that appear in the expression tree when creating a lambda expressionn (i.e. when calling <code>Expression.Lambda&lt;T&gt;(Expression, params ParameterExpression[])</code>). The Expression engine will not match types and names parameters in an expression &#8211; as far as it&#8217;s concerned different instances of <code>ParameterExpression</code> are discrete parameters.</p>

<p>Rewriting the above code yields something that doesn&#8217;t crash:</p>

<div>
<pre class="brush: csharp; title: ; notranslate">
static void ExpressionWorks() {
    var variable = Expression.Variable(typeof(ClassWithProperties));
    var expr = Expression.Equal(Expression.Property(variable, &quot;Prop&quot;), Expression.Constant(&quot;value2&quot;));

    var props = new []{ variable };
    var lambda = Expression.Lambda&lt;Func&lt;ClassWithProperties, bool&gt;&gt;(expr, props).Compile();

    var items = new List&lt;ClassWithProperties&gt; { 
        new ClassWithProperties{Prop = &quot;value1&quot;},
        new ClassWithProperties{Prop = &quot;value2&quot;},
        new ClassWithProperties{Prop = &quot;value2&quot;}
    };

    //Returns &lt;&quot;value2&quot;, &quot;value2&quot;&gt;
    items.Where(lambda);
}
</pre>
</div>

<p>As you can see, we reused the instance <code>variable</code> in both expression declaration and <code>Expression.Lambda</code> call. Everything works fine now.</p>

<h3>Getting the parameters from Expression at runtime</h3>

<p>My situation was such as that I had to deal with an already created expression. So I couldn&#8217;t simply take the variable parameters that are used to create an expression and reuse them when creating a lambda. The solution was to traverse the expression tree and get a list of all the <code>ParameterExpression</code> instances that are contained in the expression and pass those to <code>Lambda</code> function.</p>

<p>Luckily, <a href="http://msdn.microsoft.com/en-us/library/bb546136%28v=VS.90%29.aspx"><code>ExpressionVisitor</code></a> API provides an easy way to achieve this. All you have to do is inherit from <code>ExpressionVisitor</code> and implement one function to trap all the goodies we need:</p>

<div>
<pre class="brush: csharp; title: ; notranslate">
public class ParameterVisitor : ExpressionVisitor{

    List&lt;ParameterExpression&gt; m_Parameters;

    public IEnumerable&lt;ParameterExpression&gt; GetParameters(Expression expr) {
        m_Parameters = new List&lt;ParameterExpression&gt;();
        Visit(expr);
        return m_Parameters;
    }
        
    protected override System.Linq.Expressions.Expression VisitParameter(System.Linq.Expressions.ParameterExpression p) {

        if(!m_Parameters.Contains(p))
            m_Parameters.Add(p);
            
        return base.VisitParameter(p);
    }
}
</pre>
</div>

<p>We can even create an extension method to hide all complexity of creating a lambda:</p>

<div>
<pre class="brush: csharp; title: ; notranslate">
public static Func&lt;TSource, TResult&gt; CreateLambda&lt;TSource, TResult&gt;(this Expression expression) {
    var visitor = new Bluecap4.Core.Expressions.ParameterVisitor();
    var parameters = visitor.GetParameters(expression);
            
    return Expression.Lambda&lt;Func&lt;TSource, TResult&gt;&gt;(expression, parameters).Compile();
}
//Usage
static void ExpressionWorks() {
    var expr = Expression.Equal(Expression.Property(Expression.Variable(typeof(ClassWithProperties)), &quot;Prop&quot;), Expression.Constant(&quot;value2&quot;));

    var items = new List&lt;ClassWithProperties&gt; { 
        new ClassWithProperties{Prop = &quot;value1&quot;},
        new ClassWithProperties{Prop = &quot;value2&quot;},
        new ClassWithProperties{Prop = &quot;value2&quot;}
    };

    //Returns &lt;&quot;value2&quot;, &quot;value2&quot;&gt;
    items.Where(expr.CreateLambda&lt;Func&lt;ClassWithProperties,bool&gt;&gt;());
}
</pre>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.somethingorothersoft.com/2010/06/18/converting-an-expression-to-a-compiled-lambda/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

