3

Based on the context, C# can generate the expression tree for a LambdaExpression from lambda expression syntax:

Expression<Func<string, int>> expr1 = s => s.Length;

as can VB.NET:

Dim expr1 As Expression(Of Func(Of String,Integer)) = Function(s) s.Length

Why can't either language compiler generate an expression tree from other expression types?

C#:

Expression<DateTime> expr2 = DateTime.Now

VB.NET:

Dim expr2 As Expression(Of DateTime) = DateTime.Now

I am assuming this behavior is either by design; or there are technical reasons that make this unfeasable; or it is unnecessary for the requirements that made Expressions necessary in the first place -- LINQ queries. I would like further details on the subject.

3

In my opinion, the main reason this feature is not available due to the language designers not being required to implement it or not seeing point in doing that since this can be already achieved with lambdas in a sane manner.

  1. The feature is most probably technically possible, since all expressions can be written as lambdas
  2. The adoption would mean that each expression can either generate expression tree or be evaluated
    • Can lead to decrease in code readability due to big semantic difference between T and Expression<T> in comparison with Func<T> and Expression<Func<T>>
    • The ambiguity already exists for lambdas
      • Resolved automatically in VB.NET by defaulting to delegate
      • Not resolved automatically in C#, presumably the designers wanted the programmers to disambiguate between the options themselves
        • Therefore, this feature would go against previous design decisions, either defaulting to a delegate or by removing anonymous types.
  • @ZevSpitz While I cannot argue about VB, I agree with your solution on the second case. One more thing I'd like to point out is the changing meaning of return default(T) based on the return type of the function. It feels very similar to why is volatile not faring very well and making the code less understandable. On the other hand, the same return type ambiguity is with lambdas, but at least they don't look like a code that is executed right away. – Zdeněk Jelínek Jan 17 '16 at 9:09
  • "this is a code to be stored and presumably invoked later on" -- Expressions were originally designed to allow a user to write C# or VB.NET code, with type safety and Intellisense; and allow library authors to parse and transform that code into a different form. I don't see that there is any implication that the code should ever be executed as is. – Zev Spitz Jan 17 '16 at 17:27
  • the changing meaning of return default(T) based on the return type of the function -- Can you clarify what you mean by this? – Zev Spitz Jan 17 '16 at 17:31
  • @ZevSpitz Yeah, I agree that the answer is really unclear given this further comment-communication, will clean it up to bullet points. – Zdeněk Jelínek Jan 17 '16 at 17:46
  • The return default(T) case is only a build-up to show how this would cover things up - imagine a method with quite a few LoC and ending with something like return x = y;. While that might not be the brightest line, it is completely valid C# and its meaning would change dramatically based on whether the function returns T or Expression<T>. Compare that with return () => x = y - the meaning doesn't change much whether the return type is Func<T> or Expression<Func<T>> – Zdeněk Jelínek Jan 17 '16 at 18:14
1

We already know that the expression tree generation mechanism is able to generate an expression tree for any arbitrary expression, because it's able to generate an expression tree for any arbitrary expression within a lambda. So it's clear that technical limitations are not the problem. The most likely answer is that it was used only set up for automatic transformations of lambdas to expression trees because that was the only thing that LINQ needed it for, and expression trees were created for LINQ.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.