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?
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.
See more on this question at Stackoverflow