Reputation: 1142
I was thinking about the difference between Expression<Func<>>
and Func<>
, and wondered if you could convert a static method to an expression tree as follows:
class Program
{
static void Main(string[] args)
{
Func<int, int> t = x => hrm(x);
Func<int, int> t2 = new Func<int, int>(hrm);
// Works as expected:
Expression<Func<int, int>> et = x => hrm(x);
// Brokenness:
Expression<Func<int, int>> et2 = new Func<int, int>(hrm);
}
static int hrm(int x)
{
return x + 9;
}
}
What's so special about the second "Func<>" that it can't be converted to an Expression, when the first one can?
Upvotes: 1
Views: 1291
Reputation: 11177
I'd recommend you to take a look at these two blog posts: Expression Tree Basics by Charlie Calvert and my own post Generating Dynamic Methods with Expression Trees in Visual Studio 2010.
These should give you some idea about expression trees syntax and what they can and cannot do.
Upvotes: 0
Reputation: 1692
I think your confusion comes from the fact that lambdas can represent expressions or delegates (with the very same syntax) in C#. So this code:
x => hrm(x)
means something different depending on where it's written. When assigned to Func<int, int>
, it's compiled as normal to create a Func<int, int>
delegate. However, when assigned to an expression, the C# compiler defers compilation and the snippet is interpreted as an expression. Contrast this with new Func<int, int>(hrm)
, which always returns a Func<int, int>
delegate.
Upvotes: 5
Reputation: 131806
Only lambda expression are convertible into expression trees. This is why your second option won't compile.
You can create an expression tree to represent the invocation of hrm()
- but it would either be via a lambda or by creating the AST by hand. Furthermore, in neither case is the body of the hrm()
ever available as an expression tree - if that's what you were looking to do.
Upvotes: 1
Reputation: 9837
My understanding:
A lambda can be either represent an Expression or a delegate/Action/Func.
The first sample works, because the left side makes sure that you want an Expression.
The second sample doesn't work, because you create a Func<> explicitly on the right side.
Upvotes: 1