gpt4 book ai didi

c# - C# ExpressionVisitor 实现的动机是什么?

转载 作者:太空狗 更新时间:2023-10-29 19:41:00 25 4
gpt4 key购买 nike

我必须为一项任务设计一个解决方案,我想使用理论上类似于 C# 的 ExpressionVisitor 的东西。

出于好奇,我打开了 ExpressionVisitor 的 .NET 源代码来查看它。从那时起,我一直想知道为什么 .NET 团队会像他们那样实现访问者。

例如 MemberInitExpression.Accept 看起来像这样:

protected internal override Expression Accept(ExpressionVisitor visitor) {
return visitor.VisitMemberInit(this);
}

我的——可能是菜鸟——的问题是:它有意义吗?我的意思是 Accept 方法本身不应该负责它如何在自身内部实现访问吗?我的意思是我已经预料到这样的事情(删除 internal 可见性以从外部覆盖):

protected override Expression Accept(ExpressionVisitor visitor) {
return this.Update(
visitor.VisitAndConvert(this.NewExpression, "VisitMemberInit"),
visitor.Visit(this.Bindings, VisitMemberBinding)
);
}

但是这段代码在基础 ExpressionVisitorVisitMemberInit 方法中,该方法从 MemberInitExpression.Accept 调用。因此,此处的 Accept 实现似乎没有任何好处。

为什么不只处理基本 ExpressionVisitor 中的树,而忘记所有的 Accept 方法?

我希望您能理解我的观点,并希望有人能阐明这一实现背后的动机。可能我根本不了解访问者模式?...

最佳答案

访问者可以覆盖任何表达式的访问方式。如果你的建议在所有地方都得到实现,那么访客就永远不会被召唤。所有访问逻辑都在 Accept 的覆盖中。非 BCL 代码无法覆盖此方法。

如果您编写 visitor.Visit((Expression)this.SomeExpression)(就像您在问题中所做的那样),那么您将如何对 SomeExpression< 的类型执行动态调度?现在访问者必须执行动态调度。请注意,您的第二个代码片段做出了简化假设,即要访问的所有子表达式都具有已知类型。尝试为 BinaryExpression 编写代码以了解我的意思。

也许我没听懂,但这个提议没有意义。

Accept 方法的目的是性能优化。每个接受都是一个相当便宜的虚拟调用。另一种方法是在访问者中对表达式类型(它是一个枚举)进行巨大的切换。这可能更慢。

关于c# - C# ExpressionVisitor 实现的动机是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28091456/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com