How to delay / hide / wrap decision between Func<> and Expression<Func<>>

There seems to be a vital element missing in the lambda expression syntax: how does a library writer write methods / extension methods which:
  1. Allow the user to write any lambda expression
  2. Delegate the implementation to Func<> or Expression<Func<>> in a dynamic late-bound fashion.
As another poster has mentioned, we need one or more of:
  1. A way to turn Expression<Func<>> into a Func<> (i.e. an Expression<Func<>> runtime compiler / code generator).
  2. A way to express the actual argument type of a lambda expression that does not encode the choice between Expression<Func<>> and Func<>, and rather leaves the decision open.
  3. A way to turn a Func<> into an Expression<Func<>>.
Option 3 is pretty much impossible given that Func<> is a delegate, and its method pointer may refer to aribitrary IL or even unmanaged code via P/Invoke / interop.

Option 2 would be most flexible, but would require additional syntax, and would complicate the language further.

Option 1 is probably the best option: it could use Lightweight Code Generation. A cost of Option 1 would possibly be duplicated code, if the same (either isomorphic or referentially identical) expression tree was used in more than one place.

Option 1 gets my vote, not that it counts for much.


Answer this question

How to delay / hide / wrap decision between Func<> and Expression<Func<>>

  • perool

    >The Espresso example that comes with the LINQ install actually implements option 1.

    This sample to big and very difficult. It is desirable add simple sample demonstrate this technics.

    PS

    And... I'd like to see this feature at the compile-time (not only at run-time). it's open the wold of metaprogramming and make C# powerful language.

  • Rulli76

    The Espresso example that comes with the LINQ install actually implements option 1.

    Anders


  • chinafax

    Option 3 is not at all impossible, I think.  Just expand the set of operators you have.  So what if you have an expression node that says "Perform a P/Invoke to this dll method" or "Execute this tree of IL nodes"   The expression tree is simply a description, just as CodeDOM is.  Of course, you need not expect Expression -> Func -> Expression to be maintained.  The only expectation is that the expression returned is a correct description of the function from which it is derived.

    Remember that Reflector is able to, for the most part, do the more difficult problem of taking IL and turning it not into an abstract expression tree, but into legible source code.



  • How to delay / hide / wrap decision between Func<> and Expression<Func<>>