.netexceptioncatch块

以下捕获块之间有什么区别?

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

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

我知道,在任何一种情况下,exception实例都不可用,但是有什么我可以用另一个不可能实现的吗?

它们几乎是一样的。

从C#语言规范,第8.10节:

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

请注意,虽然C#在两者之间有所区别,但它们实际上与.NET 2.0相同,如本博客所述 :

感谢2.0 CLR的最新变化,如果你有代码决定抛出一个int(System.Int32),CLR现在会用RuntimeWrappedException包装它,并且编译器已经更新,为你提供了警告上面的第二个条款现在是死代码

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

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

catch (Exception)不同,不带参数的catch将捕获非符合CLS的catch (Exception)

从什么捕获(exception)/空捕获是坏的

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

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

 catch(Exception){}: catch [mscorlib]System.Exception {} 

只是简单的抓住:

 catch{}: catch [mscorlib]System.Object {} 

所以从理论上讲,如果你创建一个可以有exception的语言而不是从System.Exceptioninheritance,那就会有区别……

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

我不相信存在差异,像Resharper这样的工具会告诉你在第二个实例中catch(Exception)是多余的,除非你在Exception之前插入了其他catch(SomeSubclassException)exception处理块以应用不同的exception处理其他exception情况的逻辑。