是否可以根据泛型方法的类型实现它们的注册表

本文关键字:类型 实现 注册表 泛型方法 是否 | 更新日期: 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>。使用合适委托类型的静态字段实现泛型类型,以及查询字段或在尚未设置字段时设置字段的方法。如果需要,您甚至可以将字段的默认值设置为一个例程,该例程将检查类型以查看它是否实现了某个接口,并在适当的情况下使委托指向接口方法。