【问题标题】:Create custom exception or use built-in exceptions?创建自定义异常还是使用内置异常?
【发布时间】:2010-08-09 19:42:30
【问题描述】:

目前,我正在编写一个使用 DNS、Sockets 和 SSL 以及其他喜欢抛出异常的类的客户端类。其他人将实现这个类,所以我想知道抛出异常的最佳实践是什么。

我应该创建自己的自定义异常,以便他们知道是我的类抛出异常,还是应该允许我调用的类和方法(DNS、套接字等)抛出他们自己的异常?目前,代码有数百行,并且随着许多不同的方法调用而增长。在这种情况下抛出异常的最佳做法是什么?

【问题讨论】:

    标签: c# .net exception-handling class-design


    【解决方案1】:

    如果 BCL 包含的类已经传达了您想要的含义(例如ArgumentNullException),请使用这些类。

    为特定于您的 API 的事物保留使用您自己的异常类。

    如果您觉得可以添加信息,请务必提出您自己的异常,但不要吞下异常 - 将它们作为您自己的内部异常传播。

    【讨论】:

    • 如果您大量使用多个线程,请考虑 AggregateException - 虽然这是 .NET 4 的原生异常,但值得向后移植到 .NET 3.5 或更早版本。见msdn.microsoft.com/en-us/library/system.aggregateexception.aspx
    • 我要补充一点,如果您的自定义异常是系统扩展的特例,但仍然足够具体以证明创建自己的异常是合理的,则从该异常而不是从 Exception 继承。
    【解决方案2】:

    如果它们添加了信息,可以抛出您自己的异常,但除非存在安全问题,否则不要吞下来自底层服务的异常。

    如果您捕获一个异常并抛出一个新异常,请将旧异常分配给新异常的InnerException 属性。通过这种方式,您可以根据需要嵌套尽可能多的异常,从而创建一个分层的“视图”来了解异常的传播方式,这对调试非常有帮助。

    【讨论】:

      【解决方案3】:

      您能做的最糟糕的事情是在消息字符串中抛出一个带有详细信息的 ApplicationException。如果您发现自己需要这样做,那么是时候自定义异常了。

      【讨论】:

        【解决方案4】:

        这真的取决于你的听众,即你班级的消费者。

        例如,如果您实际上要包装许多不同的异常,则创建自定义异常可能是个好主意,这将简化使用者的错误处理。

        如果您确实创建了自定义异常,请务必将原始异常包含在自定义异常的 InnerException 中,除非您明确有理由隐藏它。这将使使用您的课程的人获得最多的可用信息,并在您的课程没有完全涵盖的异常返回时覆盖您。

        【讨论】:

          【解决方案5】:

          如果您希望任何人捕获并从您的异常中恢复,最好使用自定义异常类型的小层次结构,可能按预期的可恢复程度进行组织(例如,有一个异常类型指示“发生了意外的事情,但是socket 可能还是不错的”,另一个是“socket 状态不能被信任,但是从一个新的 socket 连接重新开始可能会起作用”,另一个是“主机说你正在做的事情不起作用;甚至不要除非您有理由相信某些事情发生了变化,否则请费心重试”)。对于“捕获”代码而言,导致异常的细节通常不如违反的后置条件的性质重要。

          【讨论】:

            猜你喜欢
            • 2019-02-21
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2023-03-04
            • 2016-04-29
            • 1970-01-01
            • 2011-04-26
            相关资源
            最近更新 更多