简体   繁体   English

这是自定义异常的好习惯吗?

[英]Is this good practice for a Custom Exception?

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

    }
}

The idea is that rather than typing this each time 这个想法是,而不是每次都输入这个

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

I'd rather write 我宁愿写

throw new PageNotFoundException();

I was going to add an overload for including the innerException however I will never use this in a try/catch block. 我打算添加一个重载来包含innerException但是我永远不会在try / catch块中使用它。

Would you consider this good practice? 你会考虑这个好习惯吗?
ie Inheriting from an exception and passing hardcoded information to base(...). 即继承异常并将硬编码信息传递给base(...)。

I decided to rewrite my answer to be specific to your actual question, and in a more broad sense that an MVC application isn't the only thing these best-practices apply to. 我决定重写我的答案以特定于您的实际问题,并且从更广泛的意义上说,MVC应用程序不是这些最佳实践适用的唯一事物。

(1) Answer. (1) 答案。 This is not good practice. 这不是好习惯。 You should use a exception builder method instead that throws HttpException directly. 您应该使用异常构建器方法,而不是直接抛出HttpException。

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

(2) DO . (2) DO Use exception builder methods (eg. the code I provided). 使用异常构建器方法(例如,我提供的代码)。 This allows for you to avoid the extra performance cost of having your own exception type, and allows for it to be inlined. 这允许您避免拥有自己的异常类型的额外性能成本,并允许它内联。 Members throwing exceptions do not get inlined. 抛出异常的成员不会被内联。 This would be the proper substitute for convenience throwing. 这将是方便投掷的正确替代品。

(3) DO . (3) DO Use base class library exceptions whenever possible, and only create a custom exception when there is absolutely no base exception that meets the needed requirements. 尽可能使用基类库异常,并且只有在绝对没有满足所需要求的基本异常时才创建自​​定义异常。 Creating custom exceptions adds deeper exception hierarchy, which makes debugging harder when it does not need to be, adds extra performance overhead, and also adds extra bloat to your code base. 创建自定义异常会增加更深层次的异常层次结构,这会使调试更加困难,增加额外的性能开销,并为代码库增加额外的膨胀。

(4) Do NOT . (4) 不要 Throw the base class System.Exception. 抛出基类System.Exception。 Use a specific exception type instead. 请改用特定的异常类型。

(5) Do NOT . (5) 不要 Create custom exceptions for convenience. 为方便起见,创建自定义异 This is not a good reason for a custom exception, because exceptions are intrinsically costly. 这不是自定义异常的好理由,因为异常本质上是昂贵的。

(6) Do NOT . (6) 不要 Create custom exceptions just to have your own exception type. 创建自定义异常只是为了拥有自己的异常类型。

(7) Do NOT . (7) 不要 Throw exceptions that can be avoided by changing the calling code. 抛出可以通过更改调用代码来避免的异常。 This would suggest that you have a usability error in the API rather than an actual problem. 这表明您在API中存在可用性错误而不是实际问题。

Anyone who has read Framework Design Guidelines from the .NET development series will know these practices, and they are very good practices. 任何阅读过.NET开发系列框架设计指南的人都会知道这些实践,并且它们是非常好的实践。 These are the very practices that the .NET framework was built upon, and MVC as well. 这些是构建.NET框架的实践,以及MVC。

If you are the one throwing the exception in the first place, then yes - it's OK. 如果你是第一个抛出异常的人,那么是的 - 没关系。 However, if you catch an HttpException and then try to throw a PageNotFoundException instead, you should put the original exception as the InnerException. 但是,如果捕获HttpException然后尝试抛出PageNotFoundException ,则应将原始异常作为InnerException。

While this is a nice construct in your own code for your own use, one consideration is that it can promote coding by convention which can be dangerous when you're dealing with other/new developers. 虽然这是您自己的代码中的一个很好的构造供您自己使用,但一个考虑因素是它可以按惯例促进编码,这在您与其他/新开发人员打交道时会很危险。

In your own libraries, if you are consistent about throwing a PageNotFoundException whenever a 404 HttpException should be thrown, it might make more sense to catch (PageNotFoundException) . 在你自己的库中,如果你在抛出404 HttpException时抛出一个PageNotFoundException是一致的,那么catch (PageNotFoundException)它会更有意义catch (PageNotFoundException) However, when you start using other libraries that don't have your custom exception, you will miss 404 HttpExceptions thrown by other code. 但是,当您开始使用没有自定义异常的其他库时,您将错过其他代码抛出的404 HttpExceptions。 Likewise, if you have other developers contributing at a later date (or even your own additions in the future), the consideration that PageNotFoundExceptions are what's being caught by most of the functionality may be missed and new 404 HttpExceptions could be thrown in the new modules, which would likewise not be caught by copy/pasted calling code. 同样,如果您有其他开发人员在以后做出贡献(或者甚至将来自己添加),可能会错过PageNotFoundExceptions被大多数功能捕获的内容,并且可能会在新模块中抛出新的404 HttpExceptions ,同样不会被复制/粘贴的调用代码捕获。

Basically, constructs like this increase the acclimation time required for working on the project, and should be handled in such a way that this cost is minimized (made sufficiently visible in an easy to find central shared objects library that isn't already too cluttered). 基本上,像这样的结构会增加处理项目所需的适应时间,并且应该以这样的方式处理,以便最小化这个成本(在一个易于查找的中央共享对象库中已经足够明显,这个库已经太杂乱了) 。

On the other hand, there is certainly value in centralizing the generation of your HttpExceptions if you're what looking for is essentially the factory pattern benefits; 另一方面,如果您正在寻找的是工厂模式的好处,那么集中生成HttpExceptions肯定是有价值的; it may be worth just going with that instead if that's what you're trying to get out of it ( throw ExceptionFactory.NewPageNotFound() ). 如果那是你想要摆脱它的东西( throw ExceptionFactory.NewPageNotFound() ),那么它可能值得去。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM