In the example below, the same lambda can be hold as an Expression
in test
but it fails to compile when it comes form a Func
:
Func<int> func = () => 2;
Expression test1 = (Expression<Func<int>>)(() => 2);
Expression test2 = (Expression<Func<int>>)(func); //does not compile
Why a lambda can be converted to an Expression
directly, but not when it is represented as a Func
?
A Func<int>
is a delegate instance - an instance of an object; it no longer has any semantic state other than "this target object reference, this method handle".
An expression tree is something much richer; it is a complex graph of the intent of code - essentially an AST. You can compile an expression to a delegate instance, but you cannot reverse a delegate to an expression tree.
When you do:
Expression<Func<int>> func = () => 2;
you are creating a complex tree; essentially:
var func = Expression.Lambda<Func<int>>(Expression.Constant(2, typeof(int)),
Array.Empty<ParameterExpression>());
(but much more complex in the general case, obviously)