繁体   English   中英

C#中的访问者模式破坏了多态(没有)(并且新的而不是覆盖的)

[英]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 )函数。

如果该语言使用动态绑定 ,则可以根据参数的实际运行时类型选择调用的函数。

通常,您可以通过不使用重载(它只是语法糖)来完全解决该问题:区分AcceptVisitorAcceptSpecialVisitor 也添加一个AcceptManagerAcceptJustSimplyMy

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM