c# – 通过反射为任何事件类型订阅动作

前端之家收集整理的这篇文章主要介绍了c# – 通过反射为任何事件类型订阅动作前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
考虑:
  1. someControl.Click += delegate { Foo(); };

事件的论据是无关紧要的,我不需要他们,我对他们不感兴趣.我只想要Foo()来调用.没有明显的方法通过反思来做同样的事情.

我想把上面的内容翻译成一些东西

  1. void Foo() { /* launch missiles etc */ }
  2.  
  3. void Bar(object obj,EventInfo info)
  4. {
  5. Action callFoo = Foo;
  6. info.AddEventHandler(obj,callFoo);
  7. }

此外,我不想假设传递给Bar的对象类型严格遵守使用事件的EventHander(TArgs)签名的准则.简单来说,我正在寻找一种方式来订阅Action到任何处理程序类型;不太简单,一种将Action代理转换为预期处理程序类型的委托的方法.

解决方法

  1. static void AddEventHandler(EventInfo eventInfo,object item,Action action)
  2. {
  3. var parameters = eventInfo.EventHandlerType
  4. .GetMethod("Invoke")
  5. .GetParameters()
  6. .Select(parameter => Expression.Parameter(parameter.ParameterType))
  7. .ToArray();
  8.  
  9. var handler = Expression.Lambda(
  10. eventInfo.EventHandlerType,Expression.Call(Expression.Constant(action),"Invoke",Type.EmptyTypes),parameters
  11. )
  12. .Compile();
  13.  
  14. eventInfo.AddEventHandler(item,handler);
  15. }
  16. static void AddEventHandler(EventInfo eventInfo,Action<object,EventArgs> action)
  17. {
  18. var parameters = eventInfo.EventHandlerType
  19. .GetMethod("Invoke")
  20. .GetParameters()
  21. .Select(parameter => Expression.Parameter(parameter.ParameterType))
  22. .ToArray();
  23.  
  24. var invoke = action.GetType().GetMethod("Invoke");
  25.  
  26. var handler = Expression.Lambda(
  27. eventInfo.EventHandlerType,invoke,parameters[0],parameters[1]),handler);
  28. }

用法

  1. Action action = () => BM_21_Grad.LaunchMissle();
  2.  
  3. foreach (var eventInfo in form.GetType().GetEvents())
  4. {
  5. AddEventHandler(eventInfo,form,action);
  6. }

猜你在找的C#相关文章