System.Linq.Expressions.ExpressionVisitor.VisitExtension和System.Linq.Expressions.ExpressionType.Extension是用于什么的?

7

System.Linq.Expressions.ExpressionVisitor有一个名为VisitExtension的方法,似乎除了在正在访问的Expression上调用VisitChildren方法之外没有任何其他作用。

protected internal virtual Expression VisitExtension(Expression node)
{
    return node.VisitChildren(this);
}

我理解VisitChildren的作用。我也明白这个虚拟实现可以被重写。从MSDN文档中,我了解到以下信息:
访问扩展表达式的子节点。这可以被重写以访问或重写特定的扩展节点。如果没有重写,则此方法将调用VisitChildren,使节点有机会遍历其子节点。默认情况下,VisitChildren将尝试减少节点。
我不认为这说明很清楚。特别是,“或重写特定的扩展节点”这句话让我无法理解。
我理解其余内容,与将表达式分解成子表达式相关。
在同一命名空间中还有一个名为ExpressionType的枚举类型,我非常了解其用途。但是,在所有成员中,有一个成员名为Extension,我无法将其映射到我目前所知道的任何语法标记。
这个文档中,也仅描述了Extension的值:
扩展表达式。
显然,ExpressionType.ExtensionExpressionVisitor.VisitExtension是相关的。
但是什么是扩展?毫无疑问,扩展方法在这种情况下没有任何作用。这里的表达式“扩展”指的是哪个语法结构?

3
你看过 https://www.re-motion.org/blogs/mix/2010/02/18/net-4-0-expression-trees-extension-expressions/ 吗? - Jeroen Mostert
谢谢,Jeroen。从URL的阅读方式来看,它似乎会对我的问题有一个非常好的答案。然而,我无法打开它。实际上,可能已经有几个月了,我一直无法打开re-motion项目网站。去年早些时候我还能打开它。 - Water Cooler v2
对于任何感兴趣的人,@JeroenMostert 提供的链接的最后一个Internet Archive版本是 https://web.archive.org/web/20131013021401/https://www.re-motion.org/blogs/mix/2010/02/18/net-4-0-expression-trees-extension-expressions/。 - Tieson T.
1个回答

14

在这种情况下,扩展不表示任何内置语法,而是对应于应用程序可以定义并赋予任意含义的节点。

当应用程序操作表达式树时,这个概念非常有用,因为这些扩展节点可以被完全集成到否则是普通表达式树的内容中。

例如,我定义了一个System.Linq.Expressions.Expression的子类,该子类具有节点类型ExpressionType.Extension,以扩展Entity Framework的LINQ,使其能够理解我们公司使用的复合主键类型。

扩展表达式类型非常有用,因为它让我可以采用两步方法:

  • 第一步,表达式访问器会将每个复合键的出现正则化为我的自定义类型的节点;
  • 第二步,负责将表达式转换为Entity Framework可以处理的内容的表达式访问器可以简单地检查类型;

例如:假设我有一个使用LINQ编写的代码:

from e in table where e.FirstKey == e.SecondKey select e;

FirstKeySecondKey 都是由多个数据库键组成时(也就是说,对于FirstKey,有两个数据库列 FirstKey1FirstKey2,对于 SecondKey 同理)。

然后第一个访问者将同时转换 e.FirstKeye.SecondKeyCustomKeyExpression 节点,从功能上将其转换为:

from e in table where Key(e.FirstKey1, e.FirstKey2) == Key(e.SecondKey1, e.SecondKey2) select e;

在第二个访问者中,当我访问EqualExpression时,我会检查两个子节点是否为CustomKeyExpression,并进行相应的转换:

from e in table where e.FirstKey1 == e.SecondKey1 && e.FirstKey2 == e.SecondKey2;

谢谢你,Jean。讲解得非常好。 - Water Cooler v2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接