[英]Polymorphism (not) broken with visitor pattern in C# (and new instead of override)
我有以下代码:
class Visitor
{
internal virtual void Visit(Node n) { }
}
class VisitorSpecial : Visitor
{
internal new void Visit(Node n) { }
}
class Base
{
internal virtual void Accept(Visitor v) { }
internal virtual void Accept(VisitorSpecial v) { }
}
class Node : Base
{
internal override void Accept(Visitor v){ v.Visit(this); }
internal override void Accept(VisitorSpecial v){ v.Visit(this); }
}
是否有任何原因为何在调用new Node().Accept(new VisitorSpecial())
时选择Accept(Visitor v)
方法new Node().Accept(new VisitorSpecial())
更新:好的,我不好,我意识到我在访问者中使用的是“新”而不是替代。 现在我知道了为什么“新突破多态性”。 这使我的问题完全愚蠢。 谢谢您的帮助。
不知道为什么选择它(可能是因为它首先在类声明中并且与提供的参数匹配),但是
Accept(VisitorSpecial v)
函数在这种情况下是没有意义的,并且似乎可以归结为对多态性的误解。 请尝试以下操作以查看原因:
class Visitor
{
internal virtual void Visit(Node n) { Console.WriteLine("In normal visitor"); }
}
class VisitorSpecial : Visitor
{
internal override void Visit(Node n) { Console.WriteLine("In special visitor"); }
}
class Base
{
internal virtual void Accept(Visitor v) { }
}
class Node : Base
{
internal override void Accept(Visitor v){ v.Visit(this); }
}
有了以上,打电话
someNode.Accept(new VisitorSpecial());
将产生输出
> In special visitor
我想您问的是特定语言(C#?)的问题。 在给定参数的情况下,由语言选择最合适的重载(注意:不要覆盖!)。 这取决于它使用的函数查找的类型 :静态(编译时)或动态(运行时)。
如果您的语言使用静态绑定 ,则它可能会选择最具体的调用,在这种情况下, n.Accept( new VisitorSpecial() )
将调用第二个重载。 然而,
Visitor v = new VisitorSpecial();
n.Accept( v );
将静态绑定到Node::Accept( Visitor )
函数。
如果该语言使用动态绑定 ,则可以根据参数的实际运行时类型选择调用的函数。
通常,您可以通过不使用重载(它只是语法糖)来完全解决该问题:区分AcceptVisitor
和AcceptSpecialVisitor
。 也添加一个AcceptManager
和AcceptJustSimplyMy
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.