2017-04-02 98 views
3

我一直在C#中实现访问者模式。我所拥有的是:在不知道C类名字的情况下铸造到基类中#

层次的类:

public class A { 
    public virtual void Accept(Visitor visitor) 
    { 
    visitor.Visit(this); 
    } 
} 

public class B : A { 
    public override void Accept(Visitor visitor) 
    { 
    visitor.Visit(this); 
    } 
} 

Visitor类:

public abstract class Visitor { 
    public virtual void Visit(A item) { 
    //... 
    } 
    public virtual void Visit(B item) { 
    Visit(item as A); 
    } 
} 

混凝土Visitor类:

public class ConcreteVisitor : Visitor { 
    public override void Visit(B item) { 
    // do something 
    // and call Visit for base class 
    Visit(item as A); // I need to know type A. 
    } 
} 

有什么办法来调用Visititem的基类不知道它的d直接的基类名称?我希望能够在不更改ConcreteVisitor类的情况下更改层次结构。

谢谢

+0

为什么你甚至有'无效访问(B项)'如果会唯一所做的就是调用'无效访问(A项)' –

+0

只需调用base.Visit(item),但您需要的事实可能是您的设计中出现其他问题的信号。 –

+0

@AdrianoRepetti我不想打电话访问基地访问者,但访问基类的项目,类似'Visit(item.AsBaseClass())' – tomwesolowski

回答

3

使之成为A的责任。随着例如方法:

public class A { 
    public virtual void Accept(Visitor visitor) 
    { 
    visitor.Visit(this); 
    } 
    public A AsBase() 
    { 
    return this; 
    } 
} 

public class ConcreteVisitor : Visitor { 
    public override void Visit(B item) { 
    // do something 
    // and call Visit for base class 
    Visit(item.AsBase()); // convert to base type 
    } 
} 

PS:你的设计也许是有点古怪,但我被你的问题的挑战;)

0

我真的相信,有一个涉及更改访问者方法标识符的更简单的解决方案:

public class ConcreteVisitor : Visitor { 
    public override void VisitB(B item) { 
    VisitA(item); 
    } 
} 

作为BA,upcast是暗示

例如,一个真实的情况可能是:

public abstract class CarVisitor 
{ 
    public virtual Engine VisitEngine(Engine engine) => engine; 

    public virtual DieselEngine VisitDieselEngine(DieselEngine engine) => engine; 
} 

public sealed class MyCarVisitor : CarVisitor 
{ 
    public override DieselEngine VisitDieselEngine(DieselEngine engine) 
    { 
      VisitEngine(engine); 

      return engine; 
    } 
} 
相关问题