代码之家  ›  专栏  ›  技术社区  ›  David_001

不同的实现类可以抛出不同的异常类型吗?

  •  1
  • David_001  · 技术社区  · 16 年前

    如果我有一个接口,我添加注释来标识将抛出一个特定的异常,那么实现类是否可以抛出 不同的 例外情况?

    一个(坏的)例子是:

    public interface IWidgetWorker {
        /// <summary>
        /// Do the work required for the specified work id.
        /// </summary>
        /// <param name="workId">The id of the piece of work to do</param>
        /// <exception cref="ArgumentException">Thrown if workId is empty</exception>
        public void DoWork(Guid workId);
    }
    
    public class DatabaseWidgetWorker : IWidgetWorker {
        public void DoWork(Guid workId) { 
            // throw some database related exception
        }
    }
    
    public class WebWidgetWorker : IWidgetWorker {
        public void DoWork(Guid workId) {
            // throw some web related exception
        }
    }
    

    也许我加了一个 WidgetWorkerException 班级?我应该在哪里记录实现类可能抛出的特定异常?

    3 回复  |  直到 16 年前
        1
  •  3
  •   Paul Turner    16 年前

    接口设计的一部分通常记录预期的异常。这些异常在创建接口时是合乎逻辑的,例如 InvalidOperationException 当一个方法被调用而对象处于错误的状态或 ArgumentOutOfRangeException 传递不正确的参数时。

    然而,接口可以以任何方式实现。实现完全可以查看文件系统或对数据库的调用,从而引入一系列在定义接口时无法预见的异常。

    您想知道方法抛出特定异常的唯一原因是能够以不同于常规异常处理的方式处理该条件。当您通过接口进行调用时,您是针对接口而不是实现进行编码的。您不知道实现是如何工作的,因此不能以任何特定的方式处理异常。您必须返回到更一般的异常处理。

    经验法则应该是在给定了公开的接口的情况下记录合理的异常,但是应该期望实现将异常抛出这些异常之外。健壮的代码将有一种机制来以通用的方式处理这些未知的异常。

        2
  •  0
  •   David Schmitt    16 年前

    实现类只应抛出接口中指定的异常。如果接口没有提供任何报告错误的可能性,那么要么接口设计不好,要么实现人员应该接受错误,因为接口用户 真的? 不在乎。

        3
  •  0
  •   Guge    16 年前

    这可能是主观的。我的感觉是,实现类应该抛出当时自然抛出的任何异常。接口不声明允许哪些异常,哪些不允许。编译器不查看您的注释,类可以抛出其他异常,仍然是接口的有效实现。

    如果出于某种原因,您需要这些异常是单个类型的,则可以捕获它们,并在调用IwidgetWorker.DoWork时将它们作为内部异常重新引发。

    WorkID为空的情况可以在调用转到实现之前处理,因此不同的实现没有理由处理相同的ArgumentException检查和抛出。

    它可能在其他编程环境中有所不同。我认为可能的例外情况必须用某些语言声明,但这里没有。

    接口的文档可以说明如何解释各种异常以及消费代码将做什么。如果异常如此等等,那么消费代码可能会在一段时间间隔后重试,但在其他情况下会终止报告错误。

    推荐文章