如果您所做的只是抛出捕获的异常,您是否需要一个 catch 块?



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

具体来说,微软关于Try Catch的文档中说。。。

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

计算机与它有什么关系?除了使用FailFast的例外(并非双关语(,调用它的进一步的try-catch块不会捕获这个异常吗?如果这就是他们的意思,man这是一种尴尬的说法!

不过,我认为这证明了不需要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();
}
}

我不完全确定作者的意思,但我有根据的猜测是"你的电脑是如何设置的"真正的意思是";您的体系结构如何处理展开"这在ARM和x86中可能有所不同。

https://github.com/dotnet/runtime/blob/master/docs/design/coreclr/botr/clr-abi.md#general-展开框架布局

catch块是不需要的,try块也是不需要的:如果他们试图保证清理,他们可以只使用using语句,因为即使出现异常,这也会起作用。

我本来打算说这是一个无用的noop。但在详细阅读了您的链接文档后,这并不完全正确。

在某些情况下,运行时可能会在不展开线程堆栈和运行任何finally块的情况下终止进程。也许如果(并且仅当(根本没有catch处理程序。你的程序无论如何都会崩溃,或者可能由于在另一个线程中处理而崩溃,你可能不在乎这种区别。

在dotnet核心中,对于某些类型的故障,运行时可能会调用Environment.FailFast并立即崩溃。尽管我认为这只是针对没有任何调用堆栈的故障,比如在恢复执行上下文时发生的异常。再说一遍,其他线程可能不会被解开。

但对于任何正在处理托管资源的finally块来说,这都是毫无意义的。我只担心finally块执行其他外部操作,比如文件重命名。然后你需要测试实际的行为是什么。

最新更新