订阅的行动,以通过反射的任何事件类型 [英] Subscribing an Action to any event type via reflection

查看:163
本文介绍了订阅的行动,以通过反射的任何事件类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑:

  someControl.Click + =委托{美孚(); };
 

本次活动的论据是不相关的,我不需要他们,我不感兴趣。我只是想富()来调用。有没有明显的方式通过反射做同样的。

我想上面翻译成沿

东西线

 无效美孚(){/ *发射导弹等* /}

空栏(obj对象,EventInfo信息)
{
    行动callFoo =富;
    info.AddEventHandler(OBJ,callFoo);
}
 

另外,我不想让这个对象传递给酒吧严格的类型符合使用EventHander(TArgs)签名活动的指导方针的前提。简单地说,我正在寻找一种方式来订阅一个采取行动的任何处理器类型;少简单地说,这样的行动代表转换成所需的处理程序类型的代表。

解决方案

 静态无效的addEventHandler(EventInfo eventInfo,目标项目,行动对行动)
{
  VAR参数= eventInfo.EventHandlerType
    .GetMethod(调用)
    .GetParameters()
    。选择(参数=>防爆pression.Parameter(parameter.ParameterType))
    .ToArray();

  VAR处理器=前pression.Lambda(
      eventInfo.EventHandlerType,
      防爆pression.Call(出pression.Constant(行动),调用,Type.EmptyTypes)
      参数
    )
    .Compile();

  eventInfo.AddEventHandler(项目,处理程序);
}
静态无效的addEventHandler(EventInfo eventInfo,目标项目,行动和LT;对象,EventArgs的>动作)
{
  VAR参数= eventInfo.EventHandlerType
    .GetMethod(调用)
    .GetParameters()
    。选择(参数=>防爆pression.Parameter(parameter.ParameterType))
    .ToArray();

  VAR调用= action.GetType()GetMethod的(调用)。

  VAR处理器=前pression.Lambda(
      eventInfo.EventHandlerType,
      防爆pression.Call(出pression.Constant(动作),调用参数,[0],参数[1]),
      参数
    )
    .Compile();

  eventInfo.AddEventHandler(项目,处理程序);
}
 

用法:

 行动行动=()=> BM_21_Grad.LaunchMissle();

  的foreach(VAR eventInfo在form.GetType()。GetEvents())
  {
    的addEventHandler(eventInfo,形式,动作);
  }
 

Consider:

someControl.Click += delegate { Foo(); };

The arguments of the event are irrelevant, I don't need them and I'm not interested in them. I just want Foo() to get called. There's no obvious way to do the same via reflection.

I'd like to translate the above into something along the lines of

void Foo() { /* launch missiles etc */ }

void Bar(object obj, EventInfo info)
{
    Action callFoo = Foo;
    info.AddEventHandler(obj, callFoo);
}

Also, I don't want to make the assumption that the type of object passed to Bar strictly adheres to the guidelines of using the EventHander(TArgs) signature for events. To put it simply, I'm looking for a way to subscribe an Action to any handler type; less simply, a way to convert the Action delegate into a delegate of the expected handler type.

解决方案

static void AddEventHandler(EventInfo eventInfo, object item,  Action action)
{
  var parameters = eventInfo.EventHandlerType
    .GetMethod("Invoke")
    .GetParameters()
    .Select(parameter => Expression.Parameter(parameter.ParameterType))
    .ToArray();

  var handler = Expression.Lambda(
      eventInfo.EventHandlerType, 
      Expression.Call(Expression.Constant(action), "Invoke", Type.EmptyTypes), 
      parameters
    )
    .Compile();

  eventInfo.AddEventHandler(item, handler);
}
static void AddEventHandler(EventInfo eventInfo, object item, Action<object, EventArgs> action)
{
  var parameters = eventInfo.EventHandlerType
    .GetMethod("Invoke")
    .GetParameters()
    .Select(parameter => Expression.Parameter(parameter.ParameterType))
    .ToArray();

  var invoke = action.GetType().GetMethod("Invoke");

  var handler = Expression.Lambda(
      eventInfo.EventHandlerType,
      Expression.Call(Expression.Constant(action), invoke, parameters[0], parameters[1]),
      parameters
    )
    .Compile();

  eventInfo.AddEventHandler(item, handler);
}

Usage:

  Action action = () => BM_21_Grad.LaunchMissle();

  foreach (var eventInfo in form.GetType().GetEvents())
  {
    AddEventHandler(eventInfo, form, action);
  }

这篇关于订阅的行动,以通过反射的任何事件类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆