ASP.NET Lab

The Best Web, The Best Future

博客园 首页 新随笔 订阅 管理

异常会在成员无法成功地完成被设计的任务时被抛出。这表示出现了执行故障。例如,如果 Connect 方法不能够连接到被指定的远程终端,那么就会引起执行故障并且抛出一个异常。

下列指导方针有助于确保你在适当的时候抛出了异常。

不要返回任何错误码。因为异常是在框架中用来报告错误的主要手段。

[异常的设计指导方针]讨论了你在通过使用异常的时候能够获得的诸多利益。

通过抛出异常的方式来报告执行故障。如果一个成员不能够成功地完成被设计的任务,那么就应该把这种情况考虑成一个执行故障并且应该抛出一个异常。
考虑通过调用 System.Environment.FailFast(System.String)(.NET Framework 2.0 中的特征)方法来终止处理的方式来替代抛出一个异常,如果你的代码遇到了一种继续执行将是不安全的情形。
不要为控件的常规流程而使用异常,如果有可能。除了系统故障和出现潜在的紊乱操作以外,框架的设计者应该设计出允许用户编写没有抛出异常的代码的 API。例如,你可以提供一种方式在调用一个成员之前对预处理进行检查,因此用户就能够编写不需要抛出异常的代码。

下列代码范例示范了在一个消息字符串是 null(在 Visual Basic 中是 Nothing)值的时候,防止异常被抛出的测试。

C#
public class Doer
{
    // 经常能够潜在地抛出异常的方法。
    public static void ProcessMessage(string message)
    {
        if (message == null)
        {
            throw new ArgumentNullException("message");
        }
    }
    // 其他方法...
}

public class Tester
{
    public static void TesterDoer(ICollection<string> messages)
    {
        foreach (string message in messages)
        {
            // 进行测试以确保调用不能够引起异常。
            if (message != null)
            {
                Doer.ProcessMessage(message);
            }
        }
    }
}

关于能够减少异常被抛出的数量的设计模式的附加信息,请参考:[异常与性能]。

考虑在抛出异常时所出现的性能牵连。
通过公开的可调用成员对所有被抛出的异常进行文档说明,因为违反成员约定(而不是系统故障)并把它们视为你的约定的一部分。作为约定组成部分的异常应该不会在一个版本到另一个版本中被改变。
不要使用既能够抛出异常又在基于一些选项的时候不能够抛出异常的公开成员。

例如,不要定义如下所示的成员:

C#
Uri ParseUri(string uriValue, bool throwOnError)
不要使用把异常作为返回值或者一个输出参数的公开成员。

这个指导方针适用于公开可见的成员。在使用一个私有的助手方法来构造并且初始化异常的时候,它是可以被接受的。

考虑使用异常建立器方法。这是从不同位置抛出相同异常的一般做法。如果要避免代码的膨胀,就可以使用助手方法来创建异常并且初始化异常属性。

助手方法必须不能够抛出异常或者堆栈追踪将不能够对通过异常而被引起的调用堆栈进行准确的反射。

不要从异常过滤区中抛出异常。在一个异常过滤器触发了一个异常的时候,被触发的异常就会通过公共语言运行时(CLR)而被捕获,并且过滤器还会返回 false 值。这种行为在过滤的执行以及明确地返回 false 并因此而变得非常难以调用的情况下是难以区分的。

但是在一些编程语言(如 C#)中并不支持异常过滤器。

避免明确地从 final 代码区中抛出异常。应该隐式地从可接受异常抛出的方法调用中抛出异常结果。
posted on 2007-02-03 16:36  Laeb  阅读(6769)  评论(0编辑  收藏  举报