简体   繁体   中英

Casting to base class without knowing name of class in C#

I've been implementing visitor pattern in C#. What I have is:

Hierarchy of classes:

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);
  }
}

The Visitor class:

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

Concrete Visitor class:

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.
  }
}

Is there any way to call Visit for item 's base class without knowing its direct base class name? I would like to be able to change hierarchy without changing ConcreteVisitor class.

Thank you

Make it the responsibility of A . With a method for example:

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

and

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: your design is maybe a bit odd, but I was challenged by your question ;)

I really believe that there's a simpler solution which involves changing visitor's method identifiers:

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

As B is A , the upcast is implicit .

For example, a real case might be:

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;
     }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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