这是自定义例外的良好做法吗?

本文关键字:自定义 | 更新日期: 2023-09-27 18:31:40

public class PageNotFoundException : HttpException
{
    public PageNotFoundException()
        : base(404, "HTTP/1.1 404 Not Found")
    {
    }
}

这个想法是,而不是每次都输入这个

throw new HttpException(404, "HTTP/1.1 404 Not Found") 

我宁愿写

throw new PageNotFoundException();

我打算添加一个重载来包含 innerException,但我永远不会在 try/catch 块中使用它。

你会考虑这个好做法吗?
即从异常继承并将硬编码信息传递给 base(...)。

这是自定义例外的良好做法吗?

我决定重写我的答案,以特定于您的实际问题,并且在更广泛的意义上,MVC 应用程序并不是这些最佳实践唯一适用的东西。

(1)回答。这不是好的做法。您应该改用直接抛出 HttpException 的异常生成器方法。

public static void ThrowPageNotFoundException() {
    throw new HttpException((Int32)HttpStatusCode.NotFound, "HTTP/1.1 404 Not Found");
}

(2)。使用异常生成器方法(例如,我提供的代码)。这允许您避免拥有自己的异常类型的额外性能成本,并允许它内联。引发异常的成员不会内联。这将是方便投掷的适当替代品。

(3)。尽可能使用基类库异常,并且仅在绝对没有满足所需要求的基异常时才创建自定义异常。创建自定义异常会增加更深层次的异常层次结构,这使得在不需要调试时更难进行调试,增加额外的性能开销,还会给代码库增加额外的膨胀。

(4)不做。抛出基类 System.Exception。请改用特定的异常类型。

(5)不要。为方便起见,创建自定义例外。这不是自定义异常的好理由,因为异常本质上是成本高昂的。

(6)不做。创建自定义例外只是为了拥有自己的异常类型。

(7)不做。引发可以通过更改调用代码来避免的异常。这表明您在 API 中存在可用性错误,而不是实际问题。

任何阅读过 .NET 开发系列中的框架设计指南的人都会知道这些实践,它们是非常好的实践。这些正是构建.NET框架和MVC的实践。

如果您是首先抛出异常的人,那么是的 - 没关系。但是,如果您捕获了一个HttpException,然后尝试抛出一个PageNotFoundException,则应将原始异常作为 InnerException。

虽然这在您自己的代码中是一个很好的结构供您自己使用,但一个考虑因素是它可以促进约定编码,这在与其他/新开发人员打交道时可能很危险。

在你自己的库中,如果你在应该抛出 404 HttpException 时始终抛出 PageNotFoundException,那么catch (PageNotFoundException) 可能更有意义。 但是,当您开始使用没有自定义异常的其他库时,您将错过其他代码引发的 404 HttpException。 同样,如果你有其他开发人员在以后的贡献(甚至是你自己将来的添加),那么PageNotFoundExceptions是大多数功能所捕获的内容的考虑可能会被遗漏,新的404 HttpExceptions可能会被抛入新模块中,同样不会被复制/粘贴的调用代码捕获。

基本上,像这样的构造增加了处理项目所需的适应时间,并且应该以最小化这种成本的方式处理(在一个易于查找的中央共享对象库中足够可见,但还没有太杂乱)。

另一方面,如果你正在寻找的本质上是工厂模式的好处,那么集中生成你的 HttpExceptions 肯定是有价值的;如果这是你试图摆脱它的东西,那么它可能值得这样做(throw ExceptionFactory.NewPageNotFound())。