2017-04-02 65 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; 
    } 
} 
相關問題