【问题标题】:What's the System.Linq.Expressions.ExpressionVisitor.VisitExtension and the System.Linq.Expressions.ExpressionType.Extension for?System.Linq.Expressions.ExpressionVisitor.VisitExtension 和 System.Linq.Expressions.ExpressionType.Extension 有什么用?
【发布时间】:2014-12-16 13:37:02
【问题描述】:

System.Linq.Expressions.ExpressionVisitor 有一个名为VisitExtension 的方法,除了在被访问的Expression 上调用VisitChildren 方法外,它似乎什么也不做。

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

我了解VisitChildren 的作用。我也明白这个虚拟实现可以并且可能意味着被覆盖。所以我从documentation of the method on MSDN收集起来,字里行间,简单评论:

访问扩展表达式的子级。 这可以被覆盖以访问或重写特定的扩展节点。 如果它没有被覆盖,这个方法将调用 VisitChildren,这让节点有机会遍历它的子节点。默认情况下,VisitChildren 会尝试减少节点。

我觉得这个解释没有帮助。具体来说,让我无法理解的短语是“或重写特定的扩展节点。”

我理解其余部分,这与将表达式简化或分解为子表达式有关。

在同一个命名空间中还有一个名为ExpressionType 的枚举,我非常了解它的用途。但在其所有成员中,有一个名为 Extension 的成员无法映射到我目前知道的任何语法标记。

documentation in this instance 也简洁得令人沮丧。它描述了Extension的值如下:

扩展表达式。

很明显,ExpressionType.ExtensionExpressionVisitor.VisitExtension 这两个是相关的。

但是什么是扩展?当然,正如显而易见的那样,扩展方法在这种情况下没有地位。 extension 表达式在这里指的是哪个语法工件?

【问题讨论】:

标签: c# .net linq expression-trees expressionvisitor


【解决方案1】:

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

当在应用程序中操作表达式树时,该概念非常有用,因为这些扩展节点可以完全集成到正常的表达式树中。

例如,我定义了 System.Linq.Expressions.Expression 的子类,节点类型为 ExpressionType.Extension,以便扩展 Entity Framework 的 LINQ 以了解我公司使用的复合主键的类型。

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

  • 在第一步中,表达式访问者会将复合键的每次出现都规范化为我的自定义类型的节点;
  • 在第二步中,负责将表达式转换为实体框架能够处理的内容的表达式访问者可以简单地检查类型;

示例:假设我编写了 LINQ 代码:

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

其中FirstKeySecondKey 都是复合数据库键(也就是说,FirstKey 有两个数据库列FirstKey1FirstKey2SecondKey 也有类似的情况)。

然后第一个访问者会将e.FirstKeye.SecondKey 都转换为CustomKeyExpression 节点,在功能上将其转换为:

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

在第二个访问者中,当我访问EqualExpression 时,我会检查两个孩子都是CustomKeyExpressions,并进行适当的转换:

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

【讨论】:

  • 谢谢你,让。解释得很好。
猜你喜欢
  • 1970-01-01
  • 2011-02-13
  • 2019-11-24
  • 2011-03-23
  • 2016-06-24
  • 2018-10-01
  • 2012-08-24
  • 2016-11-12
  • 1970-01-01
相关资源
最近更新 更多