我正在尝试编写一种方便的方法,旨在帮助将泛型委托绑定到类事件。
关键在于,类上的事件接受1个或多个参数(例如,对象和各种参数),并且我希望包装的动作接受0个参数。
一个简单的例子是:
public class Test
{
//Other class. <int,bool> is just an example, it could be anything
public event Action<int, bool> MyEvent;
//Helper
public void AddAction(Action a, object cls, string eventName)
{
var evt = cls.GetType().GetEvent(eventName);
//Need some code in here to wrap the action
evt.AddEventHandler(cls, a);
}
}
显然,上面的代码在我们尝试运行它时可能会引发异常。
编辑:我应该详细说明。我知道我可以做(a,b) => a()
,但是在这种情况下,我不知道活动的类型。
我想要的是能够生成一个新的委托,该委托接受int
,bool
然后在内部调用该动作。
我试过编写DynamicMethod / ILGenerator,但运气不佳,因此我正在寻找有关输入方法和建议。据我所知,IL生成是唯一的方法。
提前致谢。
我花了很多时间来弄清楚这一点,最终绕回了Linq Expressions。
我花了一段时间才意识到,DynamicMethod的主要问题是它没有范围。构建它时,可以将其视为一组静态指令,因此,它不知道“ this”是什么(除非您将其作为参数传递)。
我最终要做的是用期望的参数编译表达式,并在委托上调用期望的方法。
这是一些示例代码:
public static class AnonymousAction
{
public static Delegate WrapDelegate(Action action, Type targetType)
{
var invoke = targetType.GetMethod ("Invoke");
if (invoke == null)
throw new ArgumentException ("ofType must be delegate");
var parameters = invoke.GetParameters ();
var expressionParams = new ParameterExpression[parameters.Length];
for (int i=0; i<parameters.Length; ++i)
{
expressionParams [i] = Expression.Parameter (parameters [i].ParameterType);
}
var call = Expression.Call (
Expression.Constant(action),
typeof(Action).GetMethod ("Invoke")
);
return Expression.Lambda (targetType, call, expressionParams).Compile ();
}
}
public class MyReceiver
{
public event Action<MyReceiver, int> OnAction;
public void Do()
{
OnAction (this, 22);
}
}
public class Test
{
public void Run()
{
Action onAction = () => {
Console.WriteLine ("Did something");
};
var receiver = new MyReceiver ();
var evt = receiver.GetType ().GetEvent ("OnAction");
evt.AddEventHandler (receiver, AnonymousAction.WrapDelegate (onAction, evt.EventHandlerType));
receiver.Do ();
}
}
static void Main()
{
var t = new Test ();
t.Run ();
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句