根据类型处理字典中的泛型方法



我有一个通用方法

public delegate void Handler<T>(T val);

我使用户能够注册事件并提供此委托。我需要根据委托的类型保存委托列表。

我尝试保存在类型和对象的字典中。 添加方法时,我将其转换为

List<Handler<T>>

根据 T. 但是当事件发生时,我没有 T,因此无法强制转换为相关的泛型处理程序列表(我有类型但没有 T)

我通过保存每种类型的方法信息列表来解决这个问题

  private Dictionary<Type, List<MethodInfo>>  handlers = new Dictionary<Type, List<MethodInfo>>();
    public delegate void Handler<T>(T val);

    public void Register<T>( Handler<T> handler )
    {
        List<MethodInfo> lst;
        if (!handlers.TryGetValue(typeof(T), out lst))
        {
            lst = new List<MethodInfo>();
            handlers.Add(typeof(T), lst);
        }
       lst.Add(handler.Method);
    }
    public void RaiseEvent( string value)
    {
       foreach (KeyValuePair<Type, List<MethodInfo>> pair in handlers)
            {
                object typedValue;
                if (pair.Key.IsEnum)
                {
                    typedValue = Enum.Parse(pair.Key, value);
                }
                else
                {
                    typedValue = Convert.ChangeType(value, pair.Key);
                }
                foreach (MethodInfo  methodInfo  in pair.Value )
                {
                    methodInfo.Invoke(null, new[] { typedValue });
                }
            }
        }
    }

但问题是这种方法只有在该方法是静态的时才有效,否则它将需要类的类型。

这个问题有什么解决方案吗???

启用通用事件...谢谢!

也许这会有所帮助:

public delegate void Handler<in T>(T val);
private List<Delegate> m_list = new List<Delegate>();
public void AddListener<T>(Handler<T> handler) {
  m_list.Add(handler);
}
public void Call(object eventArg) {
  foreach (var handler in m_list) {
    handler.DynamicInvoke(eventArg);
  }
}

然后,如果您有这样的处理程序:

private void MyHandler(int val) {
  // Do something
}

您可以像这样将其添加到列表中:

AddListener<int>(MyHandler);

(这假设我正确地理解了你想做什么。不过我不确定。

您还可以使用非泛型委托创建处理程序存储库,如下所示:

public delegate void Handler(object val);
public delegate void Handler<T>(T val);
public class HandlerRepository
{
  private Dictionary<Type, Handler>  handlers = new Dictionary<Type, Handler>();
  public void RegisterHandler<T>(Handler<T> handler)
  {
     //error checking omitted
     //create a non-generic handler that calls the generic handler 
     //with the correct type.
     handlers.Add(typeof(T), (value)=>handler((T)value));
  }
  public void ExecuteHandler<T>(T value)
  {
     //error checking ommited
     handlers[typeof(T)](value);
  }
}

并像这样使用它:

Handler<int> handleInt = value => Console.WriteLine("Int32 is {0}", value);
Handler<string> handleString = value => Console.WriteLine("String is {0}", value);
HandlerRepository repo = new HandlerRepository();
repo.RegisterHandler(handleInt);
repo.RegisterHandler(handleString);
//this call boxes the argument to an object   
repo.ExecuteHandler(5);  // "Int32 is 5"
repo.ExecuteHandler("Hello, world"); "String is Hello, world"

相关内容

  • 没有找到相关文章

最新更新