何时以及在何种情况下使用表达式树

Dot*_*nfo 13 c# linq

我正在阅读有关表达式树功能以及如何使用lambda表达式创建委托.我仍然无法确定它在什么情况下是有用的,在我应该使用它的现实世界的例子中.

Jon*_*eet 12

表达式树的主要用途是用于进程外LINQ提供程序,例如LINQ to SQL.

当你写这样的东西:

var query = people.Where(x => x.Age > 18)
                  .Select(x => x.Name);
Run Code Online (Sandbox Code Playgroud)

那些lambda表达式可以要么被转换为代表,然后可以执行(因为它们是在LINQ到对象)它们可以被转换成表达式树,可以由查询源进行分析和作用于通过在把它们相应地(例如进入SQL,Web服务调用等).不同之处在于表达式树将代码表示为数据.如果需要,它们可以编译成代理,但通常(无论如何在LINQ中)它们从不直接执行 - 只是检查它们以找出它们包含的逻辑.

表达式树也在动态语言运行时中广泛使用,它们表示在评估动态表达式时应执行的代码.表达式树非常适合于它,因为它们可以被组合并再次分解,并且在它们被编译之后,得到的IL被JIT编译为正常.

大多数开发人员永远不需要使用表达式树API,尽管它有一些其他用途.


Chr*_*ter 5

除了LINQ之外,另一个非常简单的用例是提取属性的名称和值.我在一个流畅的API中使用它来验证数据传输对象.传递一个lambda参数来定义名称和值比使用名称的第二个字符串参数更安全,并且冒着开发人员错误的风险.

这是一个例子(减去所有安全检查和其他内务管理):

public Validator<T> Check<T>(Expression<Func<T>> expr) {
    // Analyse the expression as data
    string name = ((MemberExpression) expr.Body).Member.Name;
    // Compile and execute it to get the value
    T value = (expr.Compile())();
    return new Validator<T>(name, value);
}
Run Code Online (Sandbox Code Playgroud)

使用示例:

Check(() => x.Name).NotNull.MinLength(1);
Check(() => x.Age).GreaterThan(18);
Run Code Online (Sandbox Code Playgroud)