在不知道C#中的类名的情况下转换为基类

时间:2017-04-02 17:17:57

标签: c# oop casting visitor-pattern

我一直在用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.
  }
}

有没有办法在不知道其直接基类名称的情况下为Visit的基类调用item?我希望能够在不更改ConcreteVisitor类的情况下更改层次结构。

谢谢

2 个答案:

答案 0 :(得分: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:你的设计可能有点奇怪,但我被你的问题所挑战;)

答案 1 :(得分:0)

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

public class AUnitTests{
  @Rule
  public ExpectedException thrown= ExpectedException.none();

  @Test (expected = MyExceptionClass.class, 
  public void whenRunningSomething_shouldThrowMyExceptionWithInternalErrorCode() throws Exception {
      thrown.expect(MyExceptionClass.class);
      ??? expected return code INTERNAL_ERROR_CODE ???

      something();
  }
}

由于public class ConcreteVisitor : Visitor { public override void VisitB(B item) { VisitA(item); } } B,所以广播隐式

例如,一个真实案例可能是:

A