我为我的应用程序不期望的每个条件创建了异常。UserNameNotValidException, PasswordNotCorrectException等。

然而,我被告知我不应该为这些条件创造例外。在我的UML中,那些是主要流程的异常,那么为什么它不应该是异常呢?

是否有创建异常的指导或最佳实践?


当前回答

异常类就像“正常”类。当一个新类“是”一个不同类型的对象,具有不同的字段和不同的操作时,您可以创建一个新类。

As a rule of thumb, you should try balance between the number of exceptions and the granularity of the exceptions. If your method throws more than 4-5 different exceptions, you can probably merge some of them into more "general" exceptions, (e.g. in your case "AuthenticationFailedException"), and using the exception message to detail what went wrong. Unless your code handles each of them differently, you needn't creates many exception classes. And if it does, may you should just return an enum with the error that occured. It's a bit cleaner this way.

其他回答

异常是一种代价高昂的效果,例如,如果您有一个用户提供了无效的密码,那么通常更好的方法是返回一个失败标志,或其他一些无效的指示。

这是由于异常处理的方式,真正的错误输入和唯一的关键停止项应该是异常,而不是失败的登录信息。

抛出异常会导致堆栈unwind,这对性能有一定影响(承认,现代托管环境在这方面有所改进)。仍然在嵌套的情况下反复抛出和捕获异常是一个坏主意。

可能比这更重要的是,例外是针对特殊情况的。它们不应该用于普通的控制流,因为这会损害代码的可读性。

因为它们是正常发生的事情。异常不是控制流机制。用户经常会输入错误的密码,这不是特例。异常应该是一个真正罕见的事情,UserHasDiedAtKeyboard类型的情况。

You may use a little bit generic exceptions for that conditions. For e.g. ArgumentException is meant to be used when anything goes wrong with the parameters to a method (with the exception of ArgumentNullException). Generally you would not need exceptions like LessThanZeroException, NotPrimeNumberException etc. Think of the user of your method. The number of the conditions that she will want to handle specifically is equal to the number of the type of the exceptions that your method needs to throw. This way, you can determine how detailed exceptions you will have.

顺便说一下,总是尝试为库的用户提供一些避免异常的方法。TryParse就是一个很好的例子,它的存在使你不必使用int。解析并捕获异常。在您的情况下,您可能希望提供一些方法来检查用户名是否有效或密码是否正确,这样您的用户(或您)就不必进行大量异常处理。这将有望产生更易于阅读的代码和更好的性能。

避免抛出异常的主要原因是抛出异常涉及大量开销。

下面这篇文章指出的一件事是,例外是针对异常条件和错误的。

错误的用户名不一定是程序错误,而是用户错误……

下面是关于。net中的异常的一个不错的起点: http://msdn.microsoft.com/en-us/library/ms229030 (VS.80) . aspx