LINQ中的表达式树是什么?

Dev*_*per 6 linq

LINQ中的表达式树是什么?有人能指出我有一个代码和解释的资源?

vos*_*d01 2

表达式树是一棵所有节点都是 Expressions 的树(请耐心等待)。

我不完全确定您是否在询问表达式树的特定应用,因此这有点冗长,但应该给出使用它们的一般方法的想法。MSDN 有一些关于表达式树的通用编程概念文档,并且在 ) 中始终有实际类的文档System.Linq.Expressions。我相信,当我第一次查看表达式时,我发现这些 Microsoft 提供的示例很有用,但我记不清了。

您可能熟悉语法树的概念。例如,2 + 2通常会直观地描述语法树:

  +
 / \
2   2
Run Code Online (Sandbox Code Playgroud)

表达式树在概念上非常相似。它们是一个类似的树,其中所有节点都是一个表达式。表达式2 + 2将由代码表示

Expression.Add(Expression.Constant(2), Expression.Constant(2))
Run Code Online (Sandbox Code Playgroud)

它返回 aBinaryExpression并且是一个表达式树。


拉姆达表达式

Lambda 表达式也经常使用表达式(当使用它们时)。

这是 lambda 语句或 lambda 块:

i => {return i * 2;}
Run Code Online (Sandbox Code Playgroud)

这是一个 lambda 表达式:

i => i * 2
Run Code Online (Sandbox Code Playgroud)

您可能习惯于看到上面的代码接下来具有以下类型Func

Func<int, int> timesTwo = i => i * 2;
Run Code Online (Sandbox Code Playgroud)

然而,这样做也是有效的:

 Expression<Func<int, int>> timesTwoExpression = i => i * 2;
Run Code Online (Sandbox Code Playgroud)

在这种情况下,编译器将为表达式而不是委托生成表达式树。您可以稍后调用Compile()它来获取代表。

Func<int, int> timesTwo = timesTwoExpression.Compile()
Run Code Online (Sandbox Code Playgroud)

但是,由于表达式尚未编译,因此可以对其进行检查和/或操作。例如,我可以检查表达式的主体并确认乘法常数实际上是二。

Expression<Func<int, int>> timesTwoExpression = i => i*2;
Assert.True(timesTwoExpression.Body.NodeType == ExpressionType.Multiply);
Expression right = ((BinaryExpression) timesTwoExpression.Body).Right;
Assert.True( right.NodeType == ExpressionType.Constant);
Assert.AreEqual( ((ConstantExpression) right).Value, 2);
Run Code Online (Sandbox Code Playgroud)

我个人使用它来获取属性/方法名称为链接成员调用提供空提升运算符,并在类型仅在运行时已知时指定泛型类型的类型参数。注意:我不能保证这些链接问题的特定答案,我没有根据我编写的代码检查它们;我提供它们仅供参考和示例。

这仅允许访问表达式 API 的有限部分(您只能将其与 Lambda 表达式一起使用,而不能与 Lambda 语句一起使用),但它仍然非常有用。然而,这是一项高级功能,您的所有团队可能都不理解它,因此请负责任地使用。


LINQ 查询表达式

表达式是 LINQ 的一部分。然而,LINQ 包含相当多的 C# 功能,包括查询语法、lambda、泛型委托和表达式。

LINQ 查询在幕后使用表达式来提供一些与 C# 代码(表达式)相关的行为IQueryable. ,例如,C# 代码(表达式)被重写并作为 SQL 执行。您可能会从如何:使用表达式树构建动态查询演练:创建 IQueryable LINQ 提供程序开始,但这相当复杂。


动态代码/语言实现的表达式

我了解 Expression API 最终足够强大,可以表示大多数语言结构,并作为实现动态/解释语言的基础;尽管我从未以这种身份使用过它。您可以在与动态语言运行时相关的材料中找到有关此用途的更多信息。