c# - 带 ref / out 参数的动态事件订阅
问题描述
我一直在使用表达式树来创建委托并使用 订阅任何事件Action<Object[]>
,其中所有事件参数都转换为对象数组。到目前为止,这一直运行良好,我需要使用 out/ref 参数订阅事件,并且需要设置此参数的值。
有没有办法使用类似于表达式树的东西并订阅任何事件,但仍然能够为引发事件的对象设置/返回值?
创建委托的表达式树:
public static Delegate CreateProxyWithDynamicParameters(this EventInfo EventInfo, Action<object[]> Action)
{
var EventHandlerType = EventInfo.EventHandlerType;
var InvokeMethodInfo = EventHandlerType.GetMethod("Invoke");
var Parameters = InvokeMethodInfo.GetParameters().Select(Parameter => Expression.Parameter(Parameter.ParameterType, Parameter.Name)).ToArray();
var ConvertedParameters = Parameters.Select(Parameter => Expression.Convert(Parameter, typeof(object))).Cast<Expression>().ToArray();
var NewArrayInit = Expression.NewArrayInit(typeof(object), ConvertedParameters);
var Body = Expression.Call(Expression.Constant(Action), "Invoke", null, NewArrayInit);
var lambdaExpression = Expression.Lambda(Body, Parameters);
return Delegate.CreateDelegate(EventInfo.EventHandlerType, lambdaExpression.Compile(), InvokeMethodInfo.Name, ignoreCase: false);
}
与委托人订阅:
protected static void AddEvent<TMessage>(EventInfo eventInfo) where TMessage : EventArgs
{
void EventAction(object[] e)
{
// Run some event code.
}
var @delegate = eventInfo.CreateProxyWithDynamicParameters(EventAction);
DelegateDictionary[typeof(TMessage)] = @delegate;
eventInfo.AddEventHandler(x.Target, @delegate);
}
编辑:
这是一个简单的香草。我需要在哪里设置HandlingCode
参数。
InventorApplication.ApplicationEvents.OnSaveDocument += ApplicationEvents_OnSaveDocument;
private void ApplicationEvents_OnSaveDocument(_Document DocumentObject, EventTimingEnum BeforeOrAfter, NameValueMap Context, out HandlingCodeEnum HandlingCode)
{
HandlingCode = HandlingCodeEnum.kEventHandled;
}
解决方案
你将很难做到这一点Expression
,因为Expression
喜欢能够通过反射运行事物以进行后备,并且它不能通过反射处理 refs。您也许可以通过原始 IL 来做到这一点,但是……这变得越来越混乱。
坦率地说,这个事件 API 让你很难过。如果您控制该 API,我强烈建议使用更惯用的(object sender, SomeEventArgs args)
where SomeEventArgs : EventArgs
。然后,您SomeEventArgs
将拥有您尝试作为参数传递的所有内容的属性,并且感兴趣的代码可以执行以下操作:
args.HandlingCode = ...
分配一个值。
推荐阅读
- javascript - Webpack:库的预构建生命周期钩子
- python - 如何在 Python PyPi 正则表达式模式中引用命名捕获组
- c++ - 作为方法参数的静态方法(作为 lambda)
- node.js - 当用户连接 nodejs mongodb Stripe 时解锁具有永久访问权限的视频教程
- java - KafkaJaasLoginModuleInitializer 缓存登录配置导致问题
- php - Jquery / Ajax 表单提交不会转发 POST 数据
- list - 单击列表视图后如何获取索引
- c# - 在 C# 和 SQL Server 中添加数据
- c++ - 我应该如何在当前架构中将 json 文件提供给网站
- javascript - Filepond:几个实例导致有多个 submit.php,这不起作用