2024年3月21日发(作者:)
Exception
此类是所有异常的基类。当发生错误时,系统或当前正在执行的
应用程序通过引发包含关于该错误的信息的异常来报告错误。异常发
生后,将由该应用程序或默认异常处理程序进行处理。
Exception 类是异常从其进行继承的基类。大多数异常对象都是
Exception 的某个派生类的实例,不过,任何从 Object 类派生的对
象都可以作为异常引发。请注意,并非所有语言都支持引发和捕捉不
从 Exception 派生的对象。在几乎任何情况下,都建议仅引发和捕捉
Exception 对象。
公共语言运行库提供一种异常处理模型,该模型基于对象形式的异常
表示形式,并且将程序代码和异常处理代码分到 try 块和 catch 块
中。可以有一个或多个 catch 块,每个块都设计为处理一种特定类型
的异常,或者将一个块设计为捕捉比其他块更具体的异常。
如果应用程序将处理在执行应用程序代码块期间发生的异常,则
代码必须放置在 try 语句中。try 语句中的应用程序代码是 try 块。
处理由 try 块引发的异常的应用程序代码放在 catch 语句中,称为
catch 块。零个或多个 catch 块与一个 try 块相关联,每个 catch 块
均包含一个确定该块处理的异常类型的类型筛选器。
在 try 块中出现异常时,系统按所关联 catch 块在应用程序代码中
出现的顺序搜索它们,直到定位到处理该异常的 catch 块为止。如果
某 Catch 块的类型筛选器指定 T 或任何派生出 T 的类型,则该
catch 块处理 T 类型的异常。系统在找到第一个处理该异常的 catch
块后即停止搜索。因此,正如本节后面的示例所演示的那样,在应用
程序代码中处理某类型的 catch 块必须在处理其基类型的 catch 块
之前指定。处理 ion 的 Catch 块最后指定。
如果当前 try 块所关联的所有 catch 块均不处理该异常,且当前
try 块嵌套在当前调用的其他 try 块中,则搜索与下一个封闭 try 块
相关联的 catch 块。如果没有找到用于该异常的 catch 块,则系统
搜索当前调用中前面的嵌套级别。如果在当前调用中没有找到用于该
异常的 catch 块,则将该异常沿调用堆栈向上传递,搜索上一个堆栈
帧来查找处理该异常的 catch 块。继续搜索调用堆栈,直到该异常得
到处理或调用堆栈中没有更多的帧为止。如果到达调用堆栈顶部却没
有找到处理该异常的 catch 块,则由默认的异常处理程序处理该异
常,然后应用程序终止。
异常类型支持下面的功能:
描述错误的可读文本。当异常发生时,运行库产生文本消息通知
用户错误的性质并提供解决该问题的操作建议。此文本消息保存在异
常对象的 Message 属性中。在创建异常对象过程中,可以将文本字
符串传递给构造函数以描述该特定异常的详细信息。如果没有向构造
函数提供错误信息参数,则将使用默认错误信息。
发生异常时调用堆栈的状态。StackTrace 属性包含可以用来确定代码
中错误发生位置的堆栈跟踪。堆栈跟踪列出所有调用的方法和源文件
中这些调用所在的行号。
基类 Exception 下存在两类异常:
从 SystemException 派生的预定义公共语言运行库异常类。
从 ApplicationException 派生的用户定义的应用程序异常类。
Exception 包含很多属性,可以帮助标识异常的代码位置、类型、帮
助文件和原因:StackTrace、InnerException、Message、HelpLink、
HResult、Source、TargetSite 和 Data。
当在两个或多个异常之间存在因果关系时,InnerException 属性会维
护此信息。作为对此内部异常的反应将引发外部异常。处理外部异常
的代码可利用以前的内部异常的信息更妥当地处理错误。关于异常的
补充信息可以存储在 Data 属性中。
应本地化在创建异常对象过程中传递给构造函数的错误信息字符串,
这种字符串可以使用 ResourceManager 从资源文件提供。有关本地
化资源的更多信息,请参见“ces 命名空间概述”和“打包
和部署资源”。
若要向用户提供有关异常发生原因的大量信息,可以使用 HelpLink
属性保存帮助文件的 URL(或 URN)。
Exception 使用具有值 0x80131500 的 HRESULT
COR_E_EXCEPTION。
有关 Exception 实例的初始属性值列表,请参见 Exception 构造函
数。
性能注意事项
引发或处理异常时,将使用大量的系统资源和执行时间。引发异常只
是为了处理确实异常的情况,而不是为了处理可预知的事件或流控
制。例如,如果方法参数无效,而应用程序需要使用有效的参数调用
方法,则可以引发异常。无效的方法参数意味着出现了异常情况。相
反,用户偶尔会输入无效数据,这是可以预见的,因此如果用户输入
无效,则不要引发异常。在这种情况下,请提供重试机制以便用户输
入有效输入。
仅对特别条件引发异常,然后在应用于大多数应用程序的常规异常处
理程序中捕捉异常,而不是在应用于特定异常的处理程序中捕捉异
常。此方法的基础在于,大多数错误都可以通过验证以及与错误接近
的错误处理代码进行处理;不需要引发和捕捉异常。通用目的异常处
理程序捕捉的是在应用程序任意位置引发的、真正不可预期的异常。
此外,返回代码正常时不要引发异常;不要将返回代码转换为异
常;也不要例行公事地捕捉异常、忽略异常,然后继续处理。
using System;
class ExceptionTestClass
{
public static void Main()
{
int x = 0;
try
{
int y = 100/x;
}
catch (ArithmeticException e)
{
ine("ArithmeticException Handler: {0}", ng());
}
catch (Exception e)
{
ine("Generic Exception Handler: {0}", ng());
}
}
}
可以使用 Throw 语句显式引发异常。还可以使用 Throw 语句再
次引发捕捉的异常。好的编码做法是向再次引发的异常添加信息以在
调试时提供更多信息。
下面的代码示例使用 Try/Catch 块捕捉可能的
FileNotFoundException。Try 块后面是 Catch 块,Catch 块捕捉
FileNotFoundException,如果找不到数据文件,则向控制台写入消息。
下一条语句是 Throw 语句,该语句引发新的 FileNotFoundException
并向异常添加文本信息。
using System;
using ;
public class ProcessFile
{
public static void Main()
{
FileStream fs = null;
try
//Opens a text tile.
{
fs = new FileStream("", );
StreamReader sr = new StreamReader(fs);
string line;
//A value is read from the file and output to the console.
line = ne();
ine(line);
}
catch(FileNotFoundException e)
{
ine("[Data File Missing] {0}", e);
throw new FileNotFoundException("[ not in c:dev directory]",e);
}
finally
{
();
}
}
}
try-catch 语句由一个 try 块后跟一个或多个 catch 子句构成,这些
子句指定不同的异常处理程序。
try 块包含可能导致异常的保护代码。该块一直执行到引发异常或成
功完成为止。例如,下列强制转换 null 对象的尝试引发
NullReferenceException 异常:
object o2 = null;
try
{
int i2 = (int)o2; // Error
}
catch 子句使用时可以不带任何参数,这种情况下它捕获任何类型
的异常,并被称为一般 catch 子句。它还可以接受从
ion 派生的对象参数,这种情况下它处理特定的异常。
例如:
catch (InvalidCastException e)
{
}
在同一个 try-catch 语句中可以使用一个以上的特定 catch 子句。这
种情况下 catch 子句的顺序很重要,因为会按顺序检查 catch 子句。
将先捕获特定程度较高的异常,而不是特定程度较小的异常。
在 catch 块中可以使用 throw 语句再次引发已由 catch 语句捕获的
异常。例如:
catch (InvalidCastException e)
{
throw (e); // Rethrowing exception e
}
如果要再次引发当前由无参数的 catch 子句处理的异常,则使用不带
参数的 throw 语句。例如:
catch
{
throw;
}
在 try 块内部时应该只初始化其中声明的变量;否则,完成该块
的执行前可能发生异常。例如,在下面的代码示例中,变量 x 在 try
块内初始化。试图在 Write(x) 语句中的 try 块外部使用此变量时将
产生编译器错误:使用了未赋值的局部变量。
static void Main()
{
int x;
try
{
// Don't initialize this variable here.
x = 123;
}
catch
{
}
// Error: Use of unassigned local variable 'x'.
(x);
}


发布评论