首页 > 解决方案 > 如果您所做的只是抛出捕获的异常,您是否需要一个 catch 块?

问题描述

我发现了一些他们想要传播异常的代码,但他们想事先运行一些清理代码,所以很自然地使用Try/ Catch/ Finally。但是......他们实际上并没有做任何事情,只是转发它。在这些情况下,我的理解是不需要 catch 块,但有人说它实际上是。我不确定那些这样做的人是否正确。

具体来说,微软关于 Try-Catch 的文档说如下......

在已处理的异常中,保证运行关联的 finally 块。但是,如果异常未处理,finally 块的执行取决于异常展开操作的触发方式。反过来,这取决于您的计算机的设置方式

电脑跟它有什么关系?除了 using 的异常(没有双关语)FailFast,调用它的更进一步的 try-catch 块不会正确捕获此异常吗?如果这就是他们的意思,真是一种尴尬的说法!

不过,我认为这证明catch{ throw; }不需要,对吗?

考虑以下代码...

public static BitmapImage MakeBitmapImage(byte[] bytes){

    var ms = new MemoryStream(bytes);

    try{
        var bitmapImage = new BitmapImage();

        bitmapImage.BeginInit();
            bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
            bitmapImage.StreamSource = ms;
        bitmapImage.EndInit();

        return bitmapImage;
    }
    catch{
        throw;
    }
    finally{
        ms.Close();
        ms.Dispose();
    }
}

如果无法加载位图,难道不能像这样重写(没有catch块)来传播吗?

public static BitmapImage MakeBitmapImage(byte[] bytes){

    var ms = new MemoryStream(bytes);

    try{
        var bitmapImage = new BitmapImage();

        bitmapImage.BeginInit();
            bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
            bitmapImage.StreamSource = ms;
        bitmapImage.EndInit();

        return bitmapImage;
    }
    finally{
        ms.Close();
        ms.Dispose();
    }
}

标签: c#try-catchtry-catch-finallytry-finally

解决方案


我不完全确定作者的意思,但我有根据的猜测是“您的计算机是如何设置的”。真正的意思是“你的架构如何处理展开”。这在 ARM 和 x86 中可能有所不同。

https://github.com/dotnet/runtime/blob/master/docs/design/coreclr/botr/clr-abi.md#general-unwindframe-layout

不需要 catch 块,try 块也不需要:如果他们试图保证清理,他们可以只使用一个using语句,因为即使有异常也可以工作。


推荐阅读