[英]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.