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

Wat*_* v2 5 .net c# linq expression-trees expressionvisitor

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

protected internal virtual Expression VisitExtension(Expression node)
{
    return node.VisitChildren(this);
}
Run Code Online (Sandbox Code Playgroud)

我理解它的VisitChildren作用.我也明白这个虚拟实现可能并且可能意味着被覆盖.所以我从MSDN上的方法文档中收集到了,这些文字不用说文字和简短的评论:

访问扩展表达式的子项.可以重写此操作以访问或重写特定的扩展节点.如果没有覆盖它,这个方法将调用VisitChildren,它给节点一个机会来走它的孩子.默认情况下,VisitChildren将尝试减少节点.

我觉得这个解释没什么帮助.具体来说,让我从理解能力中解脱出来的短语是"或重写特定的扩展节点".

我理解其余部分,它涉及将表达式减少或分解为子表达式.

在同一名称空间中还有一个名为枚举的枚举ExpressionType,其目的非常清楚.但是在其所有成员中,有一个成员被命名为Extension我无法映射到我目前所知的任何语法令牌.

在这个例子中文档也是令人沮丧的简洁.它描述的值Extension如下:

扩展表达式.

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

但什么是扩展?当然,很明显,扩展方法在这种情况下没有地位.表达式扩展在哪里引用哪个语法工件?

Jea*_*nal 9

在这种情况下,扩展不代表任何类型的内置语法,但对应于应用程序可以定义和赋予任意含义的节点.

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

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

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

  • 在第一步中,表达式访问者会将该组合键的每个外观规则化为我的自定义类型的节点;
  • 在第二步中,负责将表达式转换为Entity Framework能够处理的表达式的表达式访问者可以简单地检查类型;

示例:让我们说我有编写的LINQ代码:

from e in table where e.FirstKey == e.SecondKey select e;
Run Code Online (Sandbox Code Playgroud)

FirstKeySecondKey均复合数据库键(也就是,有两个数据库列FirstKey1,并FirstKey2FirstKey,同样的SecondKey).

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

from e in table where Key(e.FirstKey1, e.FirstKey2) == Key(e.SecondKey1, e.SecondKey2) select e;
Run Code Online (Sandbox Code Playgroud)

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

from e in table where e.FirstKey1 == e.SecondKey1 && e.FirstKey2 == e.SecondKey2;
Run Code Online (Sandbox Code Playgroud)