2013-03-18 56 views
1

作为我的问题here的后续,我试图创建一个匿名事件处理程序,其参数在运行时决定。Lambda表达式或具有运行时参数的委托

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表达式和委托太多缺乏解决这一问题的认识......

匿名处理程序必须做无非转发发送者对象,事件参数和命令对象另一个功能。并不是所有的事件都有相同的参数,因此我的想法是将处理程序定义为具有动态参数的匿名函数。

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

+0

这里有一个相关的链接,只是为了让你自己了解一下你自己进入的内容:http://stackoverflow.com/questions/12865848/general-purpose-fromevent-method – Servy 2013-03-18 13:59:41

+0

有趣的例子,但地狱的维护。感谢分享:) – 2013-03-29 12:04:20

回答

0

可以声明委托/λ为取一个参数数组:

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

和里面,使用MethodInfo的类来获取有关该参数应该被转发方法的信息。

但我认为你在这里过于活跃。 Reflection允许您绕过使用编译时功能时所需的常规抽象机制。这会导致复杂性,可读性的损失,并且会将很多编译时错误转化为运行时错误。您仍然可以在运行时使用多态性和委托来决定东西,同时保持可读性和编译时类型安全性。微软在他们的库中完成了这一切。除了System.Reflection名称空间的实际实现外,您从不会看到需要使用反射的库。

+0

我最终决定我不需要这个。为发件人解决,EventArgs模式足够好。谢谢 – 2013-03-29 13:14:54