提问人:Maxim Gershkovich 提问时间:9/27/2012 更新时间:6/8/2020 访问量:13609
为什么引发或捕获的类型必须派生自 System.Exception
Why must a type thrown or caught derive from System.Exception
问:
因此,出于好奇,我想看看异常类有什么特别之处,允许它与关键字一起使用,而标准类则不能。Throw
我发现 Exception 类实现了以下内容
public class Exception : System.Object, System.Runtime.Serialization.ISerializable, System.Runtime.InteropServices._Exception
{
}
因此,我尝试实现这些相同的接口,并尝试抛出我自己的自定义异常,但无济于事。我只是被告知System.Exception
捕获或抛出的类型必须派生自
System.Exception
那么这有什么具体原因吗?我认为托管语言中的选择很少,似乎是任意的。
答:
该语言用作所有异常的基础。这实质上意味着,如果您这样做,任何可抛出或可捕获的异常都不应出错。这可能是因为使用了类的定义,以便所有异常都遵循相同的接口。由于接口一致,异常会附带堆栈跟踪和有意义的消息(例如),这对于日志记录非常宝贵。System.Exception
(Exception)myExc
System.Exception
异常是报告错误的标准机制。 应用程序和库不应使用返回代码进行通信 错误。异常的使用增加了一致的框架设计 并允许来自成员(如构造函数)的错误报告,这些成员 不能有返回类型
引发的异常是其类派生自 System.Exception,如以下示例所示。
class MyException : System.Exception {}
// ...
throw new MyException();
在 .NET Framework 中,异常是从 Exception 类
因此,您的例外必须源自 ,但这取决于您,如何在其中组织它。System.Exception
这是CLS设计者的任意选择。 据推测,他们出于一致性的原因做出了这个选择。C# 遵循 CLS;编译器出于此原因强制执行该要求,而不是出于与 Exception 类型的实现相关的任何技术原因。
CLI 实际上可以抛出任何对象。请参见 http://jilc.sourceforge.net/ecma_p3_cil.shtml#_Toc524462405。
每个异常都需要有一个通用基类的一个原因是,您可以在单个 catch 块中捕获每种类型的异常。
如果我有这个:
try
{
...
}
catch(Exception ex)
{
// Handle somehow
}
这将捕获所有异常,并允许我显示它是什么(通过使用)。ex.Message
如果你可以扔任何东西,那么你怎么会有一个可以抓住所有东西的渔获物,同时还能让你接触到扔出的物体?
你可以拥有这个,它绝对可以捕捉到一切:
try
{
...
}
catch
{
// Handle somehow
}
但是你已经“丢失”了被扔掉的东西。
评论
我认为你的前提是错误的。抛出的对象可能不是派生自 。你不能在 C# 中抛出它,也不能在 catch 子句中检查对象。从 C# 规范 (v4.0) 的第 8.10 节开始:System.Exception
某些编程语言可能支持例外,但事实并非如此 可表示为派生自 System.Exception 的对象,尽管 C# 代码永远不会生成此类异常。一般问题 子句可用于捕获此类例外。因此,一个普遍的陷阱 子句在语义上与指定类型的子句不同 System.Exception,因为前者还可以捕获以下 其他语言。
一般渔获物示例:
try
{
}
catch (Exception) { } // 'specific' catch
catch { } // 'general' catch
这在调用非托管代码时尤其重要。
有些类型似乎总是在每种语言中都得到特殊对待。主要是因为它们对系统至关重要。、 、 是 C# 中与语言关键字和 CLR 紧密绑定的特殊类型,因此不能只实现接管其角色的类也就不足为奇了。System.Exception
System.ValueType
System.Delegate
我解决了添加“系统”作为参考的问题
try
{
}
catch (System.Exception) {}
评论
throw
Exception