Casting to base class without knowing the class name in c #

I am implementing a visitor template in C #. I have:

Class hierarchy:

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

      

Class Visitor

:

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

      

Specific 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 a way to call Visit

for a item

base class without knowing its direct base class name? I would like to be able to change the hierarchy without changing the class ConcreteVisitor

.

thank

+3


source to share


2 answers


Responsibilities A

. With a method like:

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 may be a little weird, but I was challenged by your question;)

+3


source


I do believe there is a simpler solution that involves changing the visitor ids:

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

      

Because B

- A

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

      

0


source







All Articles