我有一组要执行操作的元素。经典的“访客”模式不适用于我的情况,因为: -
我的大多数访问者并不关心我的大多数元素。即使我可以使用经典的访客模式,绝大多数的访问方法都是无操作。
我想要一个访客模式的变体,如下所示: -
class Visitor
{
// called when I'm Accepted by a ThingICareAbout
void Visit(ElementICareAbout e)
{
// Do whatever needs done.
}
// called when I'm Accepted by anything else
void Visit(Element e)
{
// Do nothing.
}
}
我想出了以下内容: -
相关问题:c# generic method overload not consistent with abstract Visitor pattern
public interface IAcceptsVisitor
{
void Accept<T>( IVisitor<T> v );
}
public interface IVisitor<T>
{
void Visit( T e );
void Visit<X>( X e );
}
public class Element : IAcceptsVisitor
{
public bool Visited { get; set; }
public Element ()
{
Visited = false;
}
public void Accept<U>( IVisitor<U> v )
{
v.Visit( this );
}
}
public class Visitor : IVisitor<Element>
{
public void Visit( Element e )
{
e.Visited = true;
}
public void Visit<X>( X e )
{
// Do nothing
}
}
但是这不起作用,因为如果编译器在编译时静态地知道它将起作用,编译器只能更喜欢非泛型的Visit方法。
关于2)我已经看到Dynamic Dispatching被吹捧为访问者模式的“高级”替代方案,但这真的“更好”而不仅仅是: -
foreach (ThingICareAbout in things.OfType<ThingICareAbout>())
另外值得注意的是:我正在使用.NET 4,所以如果动态类型有帮助,我愿意试一试。
编辑:我根据动态关键字提供了自己的答案。但是,我仍然对听到其他方法非常感兴趣。
答案 0 :(得分:0)
关于Dynamic关键字,这是我到目前为止: -
public class ThingIDontCareAbout: IAcceptsVisitor
{
}
public class ThingICareAbout: IAcceptsVisitor
{
public bool Visited { get; set; }
public AdvancedElement()
{
Visited = false;
}
}
public class Visitor
{
public void Visit( IAcceptsVisitor e )
{
dynamic d = e;
this.DynamicVisit( d );
}
private void DynamicVisit( IAcceptsVisitor e )
{
// Do nothing.
}
private void DynamicVisit( ThingICareAbout e )
{
e.Visited = true;
}
}
你打电话给: -
Visitor v = new Visitor();
foreach (IAcceptsVisitor e in things) { v.Visit(e); }
去配置此vs类型检查。我特别感兴趣听到你的意见,将其与: -
进行比较foreach (ThingICareAbout e in things.OfType<ThingICareAbout>()) { ...
我喜欢动态内容包含在访问者中 - 特别是我喜欢我甚至不需要使用Accept方法污染元素类型。特别是这意味着我们可以使用它来访问不受我们控制的类型(通常是表达式或控件)。