在C#中传播在finally块中抛出的异常而不丢失catch块中的异常的最佳实践是什么?

当一个异常可以在finally块中抛出时如何传播两个异常 – 来自catch和finally?

作为一种可能的解决方案 – 使用AggregateException:

internal class MyClass
{
    public void Do()
    {
        Exception exception = null;
        try
        {
            //example of an error occured in main logic
            throw new InvalidOperationException();
        }
        catch (Exception e)
        {
            exception = e;
            throw;
        }
        finally
        {
            try
            {
                //example of an error occured in finally
                throw new AccessViolationException();
            }
            catch (Exception e)
            {
                if (exception != null)
                    throw new AggregateException(exception, e);
                throw;
            }
        }
    }
}

可以像下面的代码段一样处理这些异常:

private static void Main(string[] args)
{
    try
    {
        new MyClass().Do();
    }
    catch (AggregateException e)
    {
        foreach (var innerException in e.InnerExceptions)
            Console.Out.WriteLine("---- Error: {0}", innerException);
    }
    catch (Exception e)
    {
        Console.Out.WriteLine("---- Error: {0}", e);
    }

    Console.ReadKey();
}
最佳答案
正如评论所暗示的那样,这可能表示“不幸”的结构化代码.例如,如果您经常发现自己处于这种情况,则可能表明您正在尝试在您的方法中做太多.如果没有其他任何你可以做的事情,你只想抛出异常(你的代码被“卡住”了一个你无法编程的问题.如果有合理的期望你可以做一些有用的事情,你只想抓住一个例外框架中有一个OutOfMemoryException,但你很少会看到有人试图抓住它,因为在很大程度上它意味着你是骨头的:-)

如果finally块中的异常是try块中异常的直接结果,则返回该异常只会使实际问题变得复杂或模糊,使其难以解决.在极少数情况下,存在返回的验证原因(例如异常),那么使用AggregateException将是这样做的方法.但在采用这种方法之前,请问自己是否可以将异常分成单独的方法,其中可以返回和处理单个异常(单独处理).

转载注明原文:在C#中传播在finally块中抛出的异常而不丢失catch块中的异常的最佳实践是什么? - 代码日志