Why does expr1 compile but not expr2?
Func<object> func = () => new object();
Expression<Func<object>> expr1 = () => new object();
Expression<Func<object>> expr2 = func; //Cannot implicitly convert type 'System.Func<object>' to 'System.Linq.Expressions.Expression<System.Func<object>>'
A Func<T>
is a delegate (a pointer to a function), while an Expression<Func<T>>
is an expression tree (a tree-like data structure that describes an operation). It follows that you cannot assign one to the other, as they are completely dissimilar.
When you assign a lambda function directly to a Func<T>
the compiler compiles the code for your function and assigns a pointer to the compiled code to e.g. func
.
On the other hand, when you assign a lambda function directly to an Expression<Func<T>>
the compiler builds up the expression tree (which is simply an instance of a reference type) and assigns a reference to that object to e.g. expr1
. This is just a convenience that the compiler provides to you, giving you a much more attractive option than manually constructing the expression tree yourself in code (which of course is also completely possible).
You cannot convert between Func
and Expression
types. But you can convert from a lambda to either of them.
A lambda has a special type that only exists in the C# type system. The CLR does not know what a lambda is. Only the C# compiler knows that and the only operations that you can do with a lambda is to convert to the Func
and Expression
types. (This means that you cannot invoke a lambda for example as it has no CLR type at all).
That is why you observe a "semantic gap" here.
In simpler words the compiler can convert a chunk of code (Lambda expression) into
Expression
Func
This happens immediately when used, then the code is gone, converted non-reversible.
But Func
and Expression
are completely different types.
That's why you can't
Expression<Func<object>> expr2 = func;
But the other way around would work with
Func<object> func2 = expr1.Compile();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With