我一直在用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
类的情况下更改层次结构。
谢谢
答案 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