.net 异常捕获块

发布于 2024-10-22 06:32:51 字数 220 浏览 4 评论 0原文

以下 catch 块有什么区别?

try
{
    ...
}
catch
{
    ...
}

try
{
    ...
}
catch(Exception)
{
    ...
}

意识到,在任何一种情况下,异常实例都不可用,但是我可以用一个实例做一些其他实例做不到的事情吗?

What's the difference between the following catch blocks?

try
{
    ...
}
catch
{
    ...
}

and

try
{
    ...
}
catch(Exception)
{
    ...
}

I realize, in either case, the exception instance is not available but is there anything that I can do with one that is not possible with the other?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

音盲 2024-10-29 06:32:51

它们几乎相同。

来自 C# 语言规范,第 8.10 节:

某些编程语言可能支持不能表示为从 System.Exception 派生的对象的异常,尽管 C# 代码永远无法生成此类异常。通用的 catch 子句可用于捕获此类异常。因此,一般的 catch 子句在语义上与指定 System.Exception 类型的子句不同,因为前者还可以捕获来自其他语言的异常。

请注意,虽然 C# 区分了两者,但它们实际上与 .NET 2.0 相同,如 此博客

由于 2.0 CLR 最近的更改,如果您的代码决定在某处抛出,比如说 int (System.Int32),CLR 现在将用 RuntimeWrappedException 包装它,并且编译器已更新为警告您上面的第二个子句现在是死代码

警告 CS1058:先前的 catch 子句已捕获所有异常。所有抛出的非异常都将包装在 System.Runtime.CompilerServices.RuntimeWrappedException 中

对于 CLR 如何知道为您的程序集执行此操作,您会注意到编译器现在向您的程序集添加了一个 RuntimeCompatibilityAttribute 告诉它:
.custom 实例 void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = {property bool 'WrapNonExceptionThrows' = bool(true)}

They are almost the same.

From the C# Language Specification, section 8.10:

Some programming languages may support exceptions that are not representable as an object derived from System.Exception, although such exceptions could never be generated by C# code. A general catch clause may be used to catch such exceptions. Thus, a general catch clause is semantically different from one that specifies the type System.Exception, in that the former may also catch exceptions from other languages.

Note that while C# differentiates between the two, they are effectively the same as of .NET 2.0, as noted by this blog:

Thanks to a recent change in the 2.0 CLR, if you had code that decided to throw, say, an int (System.Int32) somewhere, the CLR will now wrap it with a RuntimeWrappedException, and the compiler has been updated to give you that warning that the second clause above is now dead code

warning CS1058: A previous catch clause already catches all exceptions. All non-exceptions thrown will be wrapped in a System.Runtime.CompilerServices.RuntimeWrappedException

For how the CLR knows to do this action for your assembly, you'll notice the compiler now adds a RuntimeCompatibilityAttribute to your assemblies telling it to:
.custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = {property bool 'WrapNonExceptionThrows' = bool(true)}

写给空气的情书 2024-10-29 06:32:51

不带参数的 catch 将捕获不符合 CLS 的异常,这与 catch (Exception) 不同。

catch without arguments will catch non CLS-compliant exceptions, unlike catch (Exception).

梦幻的味道 2024-10-29 06:32:51

来自为什么catch(Exception)/empty捕获不好

空的 catch 语句也可能同样糟糕,具体取决于您的语言生成的 MSIL 代码。 C# 将空的 catch 语句转换为 catch(System.Object),这意味着您最终会捕获所有异常 - 甚至是不符合 CLS 的异常。 VB 的表现更好,将空的 catch 语句转换为 catch e as System.Exception,这限制了您捕获符合 CLS 的异常。

From Why catch(Exception)/empty catch is bad

Empty catch statements can be just as bad, depending on the MSIL code that your language generates. C# turns an empty catch statement into catch(System.Object) which means you end up catching all exceptions - even non-CLS compliant exceptions. VB is better-behaved, turning an empty catch statement into catch e as System.Exception which limits you to catching CLS compliant exceptions.

初见 2024-10-29 06:32:51

如果你看一下生成的 IL,这里有区别:

catch(Exception){}:

catch [mscorlib]System.Exception
{}

并且只是简单的捕获:

catch{}:

catch [mscorlib]System.Object
{}

所以从理论上讲,如果你创建一种可以具有不从 System.Exception 继承的异常的语言,那么就会有区别......

If you look at the generated IL here's the difference:

catch(Exception){}:

catch [mscorlib]System.Exception
{}

and just plain catch:

catch{}:

catch [mscorlib]System.Object
{}

So in theory, if you create a language that can have exceptions NOT inherit from System.Exception, there would be a difference...

谁的新欢旧爱 2024-10-29 06:32:51

非 CLS 遵守语言(如 C++/CLI)可以抛出不是从 System.Exception 类派生的对象。第一个代码示例将允许您执行 catch 块中的代码,但您无法检查抛出的对象本身。这几乎从来都不是问题,但也可能是问题。

Non-CLS adhering languages (like C++/CLI) can throw objects not derived from System.Exception class. The first code sample will allow you to execute code in the catch block, though you can't examine the thrown object itself. This is almost never an issue, but it could be.

纵情客 2024-10-29 06:32:51

我不相信有什么区别,像 Resharper 这样的工具会告诉您在第二个实例中 catch(Exception) 是多余的,除非您还插入了其他 catch(SomeSubclassException) 异常处理块位于Exception 之前,以便对其他异常情况应用不同的异常处理逻辑。

I don't believe there is a difference, and a tool like Resharper would tell you that the catch(Exception) is redundant in the second instance, UNLESS you also inserted other catch(SomeSubclassException) exception handling blocks before Exception to apply different exception handling logic for other exception conditions.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文