Nic*_*eld 5 c# visitor-pattern
是否可以在 C# 中创建用户可扩展的访问者模式?(最好是 .net 3.5)
我在库中有一组类,我希望使用访问者模式向其中添加功能。问题是库的用户也可以创建自己的类。这意味着您需要创建一个特殊的访问者来接受新的类类型,但我们的 Accept 方法被设置为接收基本类型。如何让派生类在派生访问者中调用正确的方法。
或者是否有另一种方式来做“如果是这种类型,就这样做”?
一些示例代码:
/* In library */
namespace VisitorPattern.System
{
interface IThing
{
void Accept(SystemVisitor visitor);
void ThingMethodA(...);
void ThingMethodB(...);
}
class SystemThingA : IThing
{
public void Accept(SystemVisitor visitor) { visitor.Visit(this); }
...ThingMethods...
}
class SystemThingB : IThing
{
public void Accept(SystemVisitor visitor) { visitor.Visit(this); }
...ThingMethods...
}
class SystemThingC : IThing
{
public void Accept(SystemVisitor visitor) { visitor.Visit(this); }
...ThingMethods...
}
class SystemVisitor
{
public SystemVisitor(object specialSystemServices) { }
public virtual void Visit(SystemThingA thing) { Console.WriteLine("SystemThingA"); }
public virtual void Visit(SystemThingB thing) { Console.WriteLine("SystemThingB"); }
public virtual void Visit(SystemThingC thing) { Console.WriteLine("SystemThingC"); }
public virtual void Visit(IThing thing) { Console.WriteLine("sysvis:IThing"); }
}
}
/* in user code */
namespace VisitorPattern.User
{
using VisitorPattern.System;
class UserThingA : IThing
{
public void Accept(SystemVisitor visitor)
{
var userVisitor = visitor as UserVisitor;
if (userVisitor == null) throw new ArgumentException("visitor");
userVisitor.Visit(this);
}
...ThingMethods...
}
class UserThingB : IThing
{
public void Accept(SystemVisitor visitor)
{
var userVisitor = visitor as UserVisitor;
if (userVisitor == null) throw new ArgumentException("visitor");
userVisitor.Visit(this);
}
...ThingMethods...
}
class UserThingC : IThing
{
public void Accept(SystemVisitor visitor)
{
var userVisitor = visitor as UserVisitor;
if (userVisitor == null) throw new ArgumentException("visitor");
userVisitor.Visit(this);
}
...ThingMethods...
}
// ?????
class UserVisitor : SystemVisitor
{
public UserVisitor(object specialSystemServices, object specialUserServices) : base(specialSystemServices) { }
public void Visit(UserThingA thing) { Console.WriteLine("UserThingA"); }
public void Visit(UserThingB thing) { Console.WriteLine("UserThingB"); }
public void Visit(UserThingC thing) { Console.WriteLine("UserThingC"); }
public override void Visit(IThing thing) { Console.WriteLine("uservis:IThing"); }
}
class Program
{
static void Main(string[] args)
{
var visitor = new UserVisitor("systemservice", "userservice");
List<IThing> mylist = new List<IThing> { new UserThingA(), new SystemThingB(), new SystemThingC(), new UserThingC() };
foreach (var thing in mylist)
{
thing.Accept(visitor);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2005 次 |
| 最近记录: |