繁体   English   中英

Lambda表达式或带有运行时参数的委托

[英]Lambda expression or delegate with run-time parameters

作为在问题的后续内容,我试图创建一个匿名事件处理程序,其参数在运行时确定。

private void RegisterEventHandlers(Control ctl)
{
  foreach (Command command in CommandList)
  {
    EventInfo eventInfo = ctl.GetType().GetEvent(command.Name);

    List<ParameterExpression> callArguments = new List<ParameterExpression>();
    foreach (ParameterInfo parameter in eventInfo.EventHandlerType.GetMethod("Invoke").GetParameters())
    {
      callArguments.Add(Expression.Parameter(parameter.ParameterType, parameter.Name));
    }

    //begin pseudo code
    method = (callArguments) => 
    {
      if (sender != null) ...
      if (e != null) ...
      name = command.name;
    };
    or
    method = new delegate
    {
      if (sender != null) ...
      if (e != null) ...
      name = command.name;
    };
    //end pseudo code

    var body = Expression.Call(Expression.Constant(this), method, callArguments);
    var lambda = Expression.Lambda(eventInfo.EventHandlerType, body, callArguments);

    eventInfo.AddEventHandler(ctl, lambda.Compile());
  }
}

我发现我对lambda表达式和委托的知识非常不足以解决此问题...

匿名处理程序只需要将发送方对象,事件args和命令对象转发到另一个函数就可以。 并非所有事件都具有相同的参数,因此我想到了将处理程序定义为具有动态参数的匿名函数。

但是,最欢迎其他可能解决我的问题的解决方案。

您可以将委托/ lambda声明为采用params数组:

method = delegate(params object[] args)
{
    ...
};

在其内部,使用MethodInfo类获取有关应将参数转发到的方法的信息。

但是我认为您在这里太动态了。 通过反射,您可以绕过使用编译时功能所需的常规抽象机制。 这导致复杂性,可读性下降,并将许多编译时错误转换为运行时错误。 您仍然可以在运行时使用多态和委托来决定事物,同时保持可读性和编译时类型安全性。 Microsoft在其所有库中执行此操作。 除了在System.Reflection命名空间的实际实现中,您从未看到需要使用反射的库。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM