I am trying to understand compiler inference behavior. For example from below code snippet, run time type of compiled delegate is Func<int>
Expression addExpr = Expression.Add(Expression.Constant(2), Expression.Constant(1));
LambdaExpression lambdaExpr1 = Expression.Lambda(addExpr, null);
var compiled = lambdaExpr1.Compile();
However below line of code does not compile. Not sure what is ambiguous here for compiler to implicitly convert it into Expression<Func<int>>
and assign to variable to type LambdaExpression
LambdaExpression lambdaExp2 = ()=>2+1;
One possible reason i can guess of that lambda expression on right side could also match signature of my custom delegate in which case compiler have no way to infer delegate type. But same reason applicable to my initial code snippet. Why CLR (runtime) can decide that it can be of type Func<int>
. And if this is possible and close enough inference by runtime then why not c# compiler can also do same.
Let me begin by re-stating the question in a more concise form.
A lambda expression can be converted to
Expression<T>
whereT
is a delegate type compatible with the lambda expression.Expression<T>
is derived fromLambdaExpression
. Why then can we not convert a lambda expression directly toLambdaExpression
?
The reason is: because this is one of the rare situations in C# where type information flows from the type of the assignment target to the type of the thing being assigned. The delegate type must be known by the compiler when converting a lambda; the C# compiler does not deduce the type of the delegate from the lambda, but rather verifies that the lambda is compatible with the given delegate type.
Now, could we have designed and implemented a system whereby if the type information was not present, and the conversion target was LambdaExpression
, then a reasonable guess would be made? Sure. There was nothing stopping us other than no one wanting or needing that feature.
But the answer to the question "why doesn't this feature exist?" is always the same. We're not required to give a reason to not implement a feature. No one asked for that feature, no one designed it, implemented it, tested it, or shipped it to customers. Therefore, no feature.
Rather, non-existing features require an advocate to kick off making them into existing features. If this is a feature you want or need, then take it up on the github forum and advocate for the feature. Or implement it yourself; the compiler is open sourced.