为什么抛出或捕获的类型必须从System.Exception派生

Max*_*ich 21 .net c# compiler-errors exception

因此,出于好奇,我想看看异常类的特殊之处,它允许它与关键字一起使用,Throw而标准类则不然.

我发现的只是Exception类实现了以下内容

public class Exception : System.Object, System.Runtime.Serialization.ISerializable, System.Runtime.InteropServices._Exception
{
}
Run Code Online (Sandbox Code Playgroud)

所以我尝试实现那些相同的接口,并尝试抛出我自己的自定义异常,但并非System.Exception无效.我只是被告知

捕获或抛出的类型必须来自 System.Exception

那有什么具体的原因吗?我假设托管语言中的选择似乎很少是随意的.

Mik*_*ray 23

我认为你的前提是错误的.抛出的对象可能不是从中派生出来的System.Exception.你不能把它扔进C#或检查catch子句中的对象.从C#规范的第8.10节(v4.0):

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

一般捕获的一个例子:

try
{
}
catch (Exception) { } // 'specific' catch
catch { } // 'general' catch
Run Code Online (Sandbox Code Playgroud)

特别是,这在调用非托管代码时很重要.

有些类型似乎总是在每种语言中得到特殊待遇.主要是因为它们对系统非常重要.System.Exception,System.ValueType,System.Delegate都是特殊类型在C#中被紧密结合语言的关键字和CLR,所以这并不奇怪,你不能只是实现一个接管他们的角色类.

  • 哇,我不知道,非常感谢您扩大我的理解... (2认同)

hor*_*rgh 10

例外设计指南

例外是报告错误的标准机制.应用程序和库不应使用返回代码来传达错误.异常的使用增加了一致的框架设计,并允许来自成员(例如构造函数)的错误报告,这些成员不具有返回类型

throw(C#参考)

抛出的异常是一个对象,其类派生自System.Exception,如以下示例所示.

class MyException : System.Exception {}
// ...
throw new MyException();
Run Code Online (Sandbox Code Playgroud)

例外概述

在.NET Framework中,异常是从Exception类继承的对象

因此,您的例外必须来自System.Exception,但这取决于您如何组织它.