有没有办法在C#中简化这个reflection代理代码?
在这个响应中,我提出了以下帮助方法,可以由不同的Task
创建者重用,以将事件转换为任务完成源。
// Helper method static Task TaskFromEventHelper(object target, string eventName, Func<TaskCompletionSource, object> resultSetterFactory) { var tcs = new TaskCompletionSource(); var addMethod = target.GetType().GetEvent(eventName).GetAddMethod(); var delegateType = addMethod.GetParameters()[0].ParameterType; var d = Delegate.CreateDelegate(delegateType, resultSetterFactory(tcs), "Invoke"); addMethod.Invoke(target, new object[] {d}); return tcs.Task; } // Empty events (Action style) static Task TaskFromEvent(object target, string eventName) { return TaskFromEventHelper(target, eventName, (Func<TaskCompletionSource, object>)(tcs => (Action)(() => tcs.SetResult(null)))); } // One-value events (Action style) static Task TaskFromEvent(object target, string eventName) { return TaskFromEventHelper(target, eventName, (Func<TaskCompletionSource, object>)(tcs => (Action)(tcs.SetResult))); } // Two-value events (Action or EventHandler style) static Task<Tuple> TaskFromEvent(object target, string eventName) { return TaskFromEventHelper(target, eventName, (Func<TaskCompletionSource<Tuple>, object>)(tcs => (Action)((t1, t2) => tcs.SetResult(Tuple.Create(t1, t2))))); }
在我给出的三个例子的每一个中都使用了helper方法,有一个tcs.SetResult
组件,这让我觉得有一种方法可以将它移动到helper方法,这可能会简化签名,所以也许是帮助方法只需接受一个Func
,其中Func
将获取event
的输出并将其转换为tcs.SetResult
所需的任何tcs.SetResult
。
即,我认为必须有一种方法来创建一个助手,所以我可以写它
// Empty events (Action style) static Task TaskFromEvent(object target, string eventName) { return TaskFromEventHelper(target, eventName, new Func(() => null)); } // One-value events (Action style) static Task TaskFromEvent(object target, string eventName) { return TaskFromEventHelper(target, eventName, new Func(t => t)); } // Two-value events (Action or EventHandler style) static Task<Tuple> TaskFromEvent(object target, string eventName) { return TaskFromEventHelper<Tuple>(target, eventName, new Func<T1, T2, Tuple>(Tuple.Create)); }
,但那就是我不知道的原因?
在Func
上面。 这个例如需要?
是两个参数。 它可以以某种方式作为object
传递吗? 我觉得它有可能,但如果是这样,它需要一些真实的reflection魔法。
你可以使用Expression
:
上述就是C#学习教程:有没有办法在C#中简化这个reflection代理代码?分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
static Task TaskFromEventHelper (object target, string eventName, Delegate resultSetter) { var tcs = new TaskCompletionSource (); var addMethod = target.GetType().GetEvent(eventName).GetAddMethod(); var delegateType = addMethod.GetParameters()[0].ParameterType; var methodInfo = delegateType.GetMethod("Invoke"); var parameters = methodInfo.GetParameters() .Select(a => Expression.Parameter(a.ParameterType)) .ToArray(); // building method, which argument count and // their types are not known at compile time var exp = // (%arguments%) => tcs.SetResult(resultSetter.Invoke(%arguments%)) Expression.Lambda( delegateType, Expression.Call( Expression.Constant(tcs), tcs.GetType().GetMethod("SetResult"), Expression.Call( Expression.Constant(resultSetter), resultSetter.GetType().GetMethod("Invoke"), parameters)), parameters); addMethod.Invoke(target, new object[] { exp.Compile() }); return tcs.Task; }
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1021274.html