【问题标题】:Reflection MethodInfo.Invoke() catch exceptions from inside the method反射 MethodInfo.Invoke() 从方法内部捕获异常
【发布时间】:2011-05-06 06:11:11
【问题描述】:

我调用了MethodInfo.Invoke() 以通过反射执行函数。该调用包含在 try/catch 块中,但它仍然无法捕获我正在调用的函数引发的异常。

我收到以下消息:

用户未处理异常。


为什么MethodInfo.Invoke() 会阻止在Invoke() 之外捕获异常?
我该如何绕过它?

【问题讨论】:

    标签: c# exception reflection methods invoke


    【解决方案1】:

    您如何尝试捕获异常?通常,调用Invoke() 时抛出的是System.Reflection.TargetInvocationException 的包装异常实例。您所追求的实际异常将在 InnerException 中。

    try
    {
        method.Invoke(target, params);
    }
    catch (TargetInvocationException ex)
    {
        ex = ex.InnerException; // ex now stores the original exception
    }
    

    【讨论】:

    • 简短而简单的解决方案!
    【解决方案2】:

    编辑:据我了解,问题纯粹是 IDE 问题;您不喜欢 VS 将调用 MethodInfo 引发的异常视为未捕获,而显然不是。您可以在此处阅读有关如何解决此问题的信息:Why is TargetInvocationException treated as uncaught by the IDE? 这似乎是一个错误/设计使然;但是该答案中列出了一种或另一种体面的解决方法。

    在我看来,您有两种选择:

    1. 您可以使用MethodInfo.Invoke,捕获TargetInvocationException 并检查其InnerException 属性。您将不得不解决该答案中提到的 IDE 问题。

    2. 您可以从MethodInfo 创建一个适当的Delegate 并调用它。使用这种技术,抛出的异常将不会被包装。此外,这种方法确实似乎与调试器配合得很好;我没有收到任何“未捕获的异常”弹出窗口。

    这是一个突出两种方法的示例:

    class Program
    {
        static void Main()
        {
            DelegateApproach();
            MethodInfoApproach();
        }
    
        static void DelegateApproach()
        {
            try
            {
                Action action = (Action)Delegate.CreateDelegate
                                       (typeof(Action), GetMethodInfo());
                action();
            }
            catch (NotImplementedException nie)
            {
    
            }
         }
    
        static void MethodInfoApproach()
        {
            try
            {
                GetMethodInfo().Invoke(null, new object[0]);
            }
            catch (TargetInvocationException tie)
            {
                if (tie.InnerException is NotImplementedException)
                {
    
    
                }
            }
        }
    
        static MethodInfo GetMethodInfo()
        {
            return typeof(Program)
                    .GetMethod("TestMethod", BindingFlags.NonPublic | BindingFlags.Static);
        }    
    
        static void TestMethod()
        {
            throw new NotImplementedException();
        }
    }
    

    【讨论】:

    • 我正面临这个问题,在 .NET5 中它根本不会抛出异常。我尝试使用 VS 2019 16.9.3 和 Rider 2020.3。方法内部抛出的异常是 System.Net.Http 异常。我应该在我的项目中添加必要的包以便能够特别捕获那个包吗?
    • 更新我的评论:调用的方法是一个异步任务之一,所以我不得不用 await (Task) method.Invoke(instance, null); 调用它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-14
    • 2021-12-23
    • 2013-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多