首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >参数个数可变的动态调用中的受控异常处理

参数个数可变的动态调用中的受控异常处理
EN

Stack Overflow用户
提问于 2012-03-18 22:54:21
回答 1查看 514关注 0票数 3

在一个thread resolved yesterday中,@hvd向我展示了在处理未知类型的委托时,如何“控制”.Invoke的异常处理(这个问题出现在像Isis2这样的库中,最终用户提供多态事件处理程序和库类型匹配来决定调用哪个)。Hvd的建议围绕着知道upcall处理程序接收了多少参数,然后使用该信息来构造正确类型的泛型,从而允许他构造动态对象并调用它。该序列产生了对异常处理的完全控制。

他的建议的核心是Isis2可以考虑这样做:

代码语言:javascript
复制
MethodInfo mi = typeof(Program).GetMethod("Foo", BindingFlags.Static | BindingFlags.NonPublic); 
Delegate del = Delegate.CreateDelegate(typeof(Action<,>).MakeGenericType(mi.GetParameters().Select(p => p.ParameterType).ToArray()), mi);
((dynamic)del).Invoke(arg0, arg1);

这是我的问题:有没有人能提出一种方法来做同样的事情,对任意数量的参数都有效?显然,我可以针对1arg、2等情况执行一个switch语句并编写代码。但是有没有办法让mi.GetParameters().Length告诉我们有多少个参数?

作为那些不想单击链接的人的概要,核心问题是:当执行这些类型的动态向上调用时,最终用户(注册了被调用的方法)可能会因为bug而抛出异常。事实证明,当不在Visual Studio下运行时--当直接在CLR中运行时-- C# .Invoke将捕获并重新引发异常,将它们打包为InvocationTargetException中的内部异常。这将展开堆栈,并导致用户认为调用.Invoke的代码(例如,我的代码)存在某种问题。这就是为什么C#参考手册认为捕获/重新抛出是糟糕的编码实践:一个人应该只捕获自己计划处理的异常...

hvd解释说,这基本上是因为.Invoke不知道参数的数量或类型,在这种模式下,显然,出于某种原因,会捕获和重新抛出异常。他的变通方法基本上限制了参数的数量(本例中的泛型是: Action<,>),这显然就足够了,这样.Invoke就不会做“通用捕获”了。但要将他的示例用于任意代码,我需要为每个可能的参数数量提供一个案例。可行的(毕竟,谁会想要超过16个呢?)但是丑陋!

因此,今天挑战是:改进代码,以便使用类似的3行C#代码段,无论参数有多少,它都能正常工作。当然,产生的委托也需要是可调用的,假设有一个对象向量,每个参数一个...

PS:悲观的一个原因:行动本身有16种形式,有1到16个论点。因此,对我来说,这表明C#开发人员没有看到更通用的方法,最终得到了与我使用switch语句相对应的版本(我猜switch语句适用于0到16个参数,因为我需要一个带有N个类型参数的Action<...>来处理N个用户提供的参数!)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-03-24 05:03:39

我不想让它永远开放,所以我已经尽我所能来理解核心问题,包括下载Mono中的.Invoke代码。据我所知,最初的问题只是由于一种优化,当在具有参数向量的对象上执行动态调用时,该优化以捕获异常为代价来支持更快的调用。使用泛型模板创建的动态委托的代码中根本没有这个catch。

这不是一个很好的答案,但如果不访问Invoke的.NET实现,显然不可能给出更好的答案。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9759305

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档