Hi.
Намучившись к кодом, подобным
switch(nodeName)
{
case "Node1": handleNode1(node); break;
case "Node2": handleNode2(node); break;
...
case "Node543": handleNode543(node); break;
}
я придумал следующий диспетчер:
using System;
using System.Reflection;
using System.Collections;
namespace utils
{
public class DuplicateDefaultDispatcherException : ApplicationException
{
public DuplicateDefaultDispatcherException() {}
public DuplicateDefaultDispatcherException(string msg) : base(msg) {}
public DuplicateDefaultDispatcherException(string msg, Exception inner) : base(msg, inner) {}
}
[AttributeUsage(AttributeTargets.Method)]
public class DispatchByAttribute : Attribute
{
public DispatchByAttribute(object a) { _a = a; }
public object attribute { get { return _a; } }
private object _a;
}
[AttributeUsage(AttributeTargets.Method)]
public class DefaultDispatcherAttribute : Attribute
{
}
public class CustomDispatcher
{
protected CustomDispatcher()
{
}
protected void EnumerateHandlers(Type dt)
{
foreach(MemberInfo mi in this.GetType().GetMembers(BindingFlags.Instance | BindingFlags.Public))
{
DispatchByAttribute dba = (DispatchByAttribute)Attribute.GetCustomAttribute(mi, typeof(DispatchByAttribute));
if(dba != null)
{
_Handlers.Add(dba.attribute, Delegate.CreateDelegate(dt, this, mi.Name));
prj2make.MessageLog.Info("mi.name");
}
DefaultDispatcherAttribute da = (DefaultDispatcherAttribute)Attribute.GetCustomAttribute(mi, typeof(DefaultDispatcherAttribute));
if(da != null)
{
if(_DefaultHandler != null)
throw new DuplicateDefaultDispatcherException("Second Default Handler");
_DefaultHandler = Delegate.CreateDelegate(dt, this, mi.Name);
}
}
}
protected Delegate GetHandler(object o)
{
if(_Handlers.Contains(o))
return (Delegate)_Handlers[o];
return _DefaultHandler;
}
private SortedList _Handlers = new SortedList();
private Delegate _DefaultHandler = null;
}
}
Может, кому пригодится...
Принимать внутрь так:
public delegate void DelegateType();
public class StringDispatcherTestImpl : CustomDispatcher
{
[DispatchBy("one")]
public void One()
{
}
[DispatchBy("two")]
public void Two()
{
}
[DefaultDispatcher()]
public void Default()
{
}
public StringDispatcherTestImpl()
{
EnumerateHandlers(typeof(DelegateType));
}
}
После чего получать обработчик посредством
GetHandler(o);
Здравствуйте, m.a.g., Вы писали:
MAG>Hi.
MAG>Намучившись к кодом, подобным
MAG>MAG>switch(nodeName)
MAG>{
MAG>case "Node1": handleNode1(node); break;
MAG>case "Node2": handleNode2(node); break;
MAG>...
MAG>case "Node543": handleNode543(node); break;
MAG>}
MAG>
Обычно это говорит о недостатке проэктирования и в таком случае используется DP Visitor.