Why would you use Expression> rather than Func?

后端 未结 10 1960
隐瞒了意图╮
隐瞒了意图╮ 2020-11-22 00:32

I understand lambdas and the Func and Action delegates. But expressions stump me.

In what circumstances would you use an Expression

相关标签:
10条回答
  • 2020-11-22 00:40

    LINQ is the canonical example (for example, talking to a database), but in truth, any time you care more about expressing what to do, rather than actually doing it. For example, I use this approach in the RPC stack of protobuf-net (to avoid code-generation etc) - so you call a method with:

    string result = client.Invoke(svc => svc.SomeMethod(arg1, arg2, ...));
    

    This deconstructs the expression tree to resolve SomeMethod (and the value of each argument), performs the RPC call, updates any ref/out args, and returns the result from the remote call. This is only possible via the expression tree. I cover this more here.

    Another example is when you are building the expression trees manually for the purpose of compiling to a lambda, as done by the generic operators code.

    0 讨论(0)
  • 2020-11-22 00:45

    When you want to treat lambda expressions as expression trees and look inside them instead of executing them. For example, LINQ to SQL gets the expression and converts it to the equivalent SQL statement and submits it to server (rather than executing the lambda).

    Conceptually, Expression<Func<T>> is completely different from Func<T>. Func<T> denotes a delegate which is pretty much a pointer to a method and Expression<Func<T>> denotes a tree data structure for a lambda expression. This tree structure describes what a lambda expression does rather than doing the actual thing. It basically holds data about the composition of expressions, variables, method calls, ... (for example it holds information such as this lambda is some constant + some parameter). You can use this description to convert it to an actual method (with Expression.Compile) or do other stuff (like the LINQ to SQL example) with it. The act of treating lambdas as anonymous methods and expression trees is purely a compile time thing.

    Func<int> myFunc = () => 10; // similar to: int myAnonMethod() { return 10; }
    

    will effectively compile to an IL method that gets nothing and returns 10.

    Expression<Func<int>> myExpression = () => 10;
    

    will be converted to a data structure that describes an expression that gets no parameters and returns the value 10:

    larger image

    While they both look the same at compile time, what the compiler generates is totally different.

    0 讨论(0)
  • 2020-11-22 00:46

    The primary reason is when you don't want to run the code directly, but rather, want to inspect it. This can be for any number of reasons:

    • Mapping the code to a different environment (ie. C# code to SQL in Entity Framework)
    • Replacing parts of the code in runtime (dynamic programming or even plain DRY techniques)
    • Code validation (very useful when emulating scripting or when doing analysis)
    • Serialization - expressions can be serialized rather easily and safely, delegates can't
    • Strongly-typed safety on things that aren't inherently strongly-typed, and exploiting compiler checks even though you're doing dynamic calls in runtime (ASP.NET MVC 5 with Razor is a nice example)
    0 讨论(0)
  • 2020-11-22 00:51

    Overly simplified here, but Func is a machine, whereas Expression is a blueprint. :D

    0 讨论(0)
  • 2020-11-22 00:56

    An extremely important consideration in the choice of Expression vs Func is that IQueryable providers like LINQ to Entities can 'digest' what you pass in an Expression, but will ignore what you pass in a Func. I have two blog posts on the subject:

    More on Expression vs Func with Entity Framework and Falling in Love with LINQ - Part 7: Expressions and Funcs (the last section)

    0 讨论(0)
  • 2020-11-22 00:58

    You would use an expression when you want to treat your function as data and not as code. You can do this if you want to manipulate the code (as data). Most of the time if you don't see a need for expressions then you probably don't need to use one.

    0 讨论(0)
提交回复
热议问题