是否可以根据泛型方法的类型实现它们的注册表
本文关键字:类型 实现 注册表 泛型方法 是否 | 更新日期: 2023-09-27 18:25:20
这里有一个方法委托:
delegate void ExceptionHandelr<T>(T exception,out bool handeled) where T:Exception;
我想有一个这类方法的注册表,这样我就可以根据它们的方法类型来调用它们,比如:
var method=ErrorHandlers[typeof(NullReferenceException)];
method(exception as NullReferenceException,out handled);
如何实现此注册表?我不能有Dictionary<T,Method<T>>
,可以吗?
我会这样做:
using System;
using System.Collections.Generic;
using System.Reflection;
namespace Test
{
class MainApp
{
public class ExceptionRegistry
{
Dictionary<Type, object> registry = new Dictionary<Type, object>();
private Func<T, bool> Get<T>() where T : Exception
{
return registry[typeof(T)] as Func<T, bool>;
}
private bool Invoke<T>(T exception) where T : Exception
{
return Get<T>().Invoke(exception);
}
public bool Invoke(Exception exception)
{
MethodInfo method = this.GetType().GetMethod("Invoke", BindingFlags.NonPublic | BindingFlags.Instance);
MethodInfo generic = method.MakeGenericMethod(exception.GetType());
var result = generic.Invoke(this, new object[] { exception });
return (bool)result;
}
public void Add<T>(Func<T, bool> handler) where T : Exception
{
registry.Add(typeof(T), handler);
}
}
static void Main()
{
ExceptionRegistry registry = new ExceptionRegistry();
registry.Add<ArgumentException>((ArgumentException exception) =>
{
// some logic
return true;
});
Exception ex = new ArgumentException();
bool result = registry.Invoke(ex);
}
}
}
我将创建一个Dictionary<Type, Delegate>
,然后使用DynamicInvoke
方法执行委托。
http://msdn.microsoft.com/en-us/library/system.delegate.dynamicinvoke.aspx
答案有点晚,但我还是想给出:)
您可以使用一个静态的、通用的助手类来以强类型的、类型安全的方式存储和检索处理程序:
public static class ExceptionHandlers<TEx>
where TEx : Exception
{
public static ExceptionHandler<TEx> Handle
{
get;
set;
}
}
你可以在一个地方分配处理程序:
public static void MyExceptionHandler(MyException exception, out bool handled)
{
// Handling logic...
}
...
ExceptionHandlers<MyException>.Handle = MyExceptionHandler;
并在任何需要的地方使用它们:
try
{
// Something...
}
catch(MyException myEx)
{
bool handled;
ExceptionHandlers<MyException>.Handle(myEx, out handled);
}
当使用不同的TEx
类型时,每个唯一的ExceptionHandler<TEx>
的单个实例都会在运行时创建,并且根据需要,您有不带强制转换的处理程序:)
如果需要,也可以很容易地扩展此解决方案以使用处理程序的集合。
可以有一个如您所描述的字典,但更好的模式是遵循Comparer<T>
。使用合适委托类型的静态字段实现泛型类型,以及查询字段或在尚未设置字段时设置字段的方法。如果需要,您甚至可以将字段的默认值设置为一个例程,该例程将检查类型以查看它是否实现了某个接口,并在适当的情况下使委托指向接口方法。