How do I build an expression with a certain signature?

I'm trying to call a method with a parameter of type Expression<Func<T, string>> but the expression tree that I build doesn't allow me to call the method. Here's a short but complete program demonstrating the problem:

using System;
using System.Linq.Expressions;

public class Test
{
    public string Name { get { return ""; } }

    public static void Main()
    {
        Foo<Test>();
    }

    static void Foo<T>()
    {
        var parameter = Expression.Parameter(typeof(T), "t");
        var property = Expression.Property(parameter, "Name");
        var lambda = Expression.Lambda(property, parameter);
        Bar<T>(lambda);
    }

    static void Bar<T>(Expression<Func<T, string>> expression) {}
}

Error:

error CS1503: Argument 1: cannot convert from
'System.Linq.Expressions.LambdaExpression' to 
'System.Linq.Expressions.Expression<System.Func<T, string>>'

How can I pass my expression tree to the method?

Jon Skeet
people
quotationmark

You're actually already building an expression tree which has the right type at execution time (if you just don't try to call the method, and print out the type of the object that the value of lambda refers to). However, the compile-time type of lambda is just LambdaExpression, not Expression<Func<T, string>>. That's because you're using a non-generic overload of Expression.Lambda which is designed to be used when you don't know the desired expression tree type at compile-time. That does the right thing at execution time, but doesn't allow you to use it in a strongly-typed way.

Fortunately, you do know the type of the expression tree you want to produce, so you just need to specify that in a call to a generic overload of Expression.Lambda:

var lambda = Expression.Lambda<Func<T, string>>(property, parameter);

That will throw an exception at execution time if the expression tree you've built up doesn't have the right type, e.g. if the Value1 property is of the wrong type.

people

See more on this question at Stackoverflow