我为我的应用程序不期望的每个条件创建了异常。UserNameNotValidException, PasswordNotCorrectException等。
然而,我被告知我不应该为这些条件创造例外。在我的UML中,那些是主要流程的异常,那么为什么它不应该是异常呢?
是否有创建异常的指导或最佳实践?
我为我的应用程序不期望的每个条件创建了异常。UserNameNotValidException, PasswordNotCorrectException等。
然而,我被告知我不应该为这些条件创造例外。在我的UML中,那些是主要流程的异常,那么为什么它不应该是异常呢?
是否有创建异常的指导或最佳实践?
当前回答
在决定异常是否合适时,需要考虑一些有用的事情:
what level of code you want to have run after the exception candidate occurs - that is, how many layers of the call stack should unwind. You generally want to handle an exception as close as possible to where it occurs. For username/password validation, you would normally handle failures in the same block of code, rather than letting an exception bubble up. So an exception is probably not appropriate. (OTOH, after three failed login attempts, control flow may shift elsewhere, and an exception may be appropriate here.) Is this event something you would want to see in an error log? Not every exception is written to an error log, but it's useful to ask whether this entry in an error log would be useful - i.e., you would try to do something about it, or would be the garbage you ignore.
其他回答
异常是一种代价高昂的效果,例如,如果您有一个用户提供了无效的密码,那么通常更好的方法是返回一个失败标志,或其他一些无效的指示。
这是由于异常处理的方式,真正的错误输入和唯一的关键停止项应该是异常,而不是失败的登录信息。
抛出异常会导致堆栈unwind,这对性能有一定影响(承认,现代托管环境在这方面有所改进)。仍然在嵌套的情况下反复抛出和捕获异常是一个坏主意。
可能比这更重要的是,例外是针对特殊情况的。它们不应该用于普通的控制流,因为这会损害代码的可读性。
在决定异常是否合适时,需要考虑一些有用的事情:
what level of code you want to have run after the exception candidate occurs - that is, how many layers of the call stack should unwind. You generally want to handle an exception as close as possible to where it occurs. For username/password validation, you would normally handle failures in the same block of code, rather than letting an exception bubble up. So an exception is probably not appropriate. (OTOH, after three failed login attempts, control flow may shift elsewhere, and an exception may be appropriate here.) Is this event something you would want to see in an error log? Not every exception is written to an error log, but it's useful to ask whether this entry in an error log would be useful - i.e., you would try to do something about it, or would be the garbage you ignore.
抛出异常的经验法则非常简单。当你的代码进入UNRECOVERABLE INVALID状态时,你可以这样做。如果数据被泄露,或者您无法回溯到目前为止发生的处理,那么您必须终止它。你还能做什么呢?您的处理逻辑最终将在其他地方失败。如果你能以某种方式恢复,那么就这样做,不要抛出异常。
在你的特定情况下,如果你被迫做一些愚蠢的事情,比如接受提款,然后才检查用户/密码,你应该通过抛出一个异常来终止这个过程,通知发生了一些不好的事情,并防止进一步的损害。
以下是我的建议:
我不认为这总是一个抛出异常的好方法,因为它将花费更多的时间和内存来处理这样的异常。
在我看来,如果某些事情可以用“友好、礼貌”的方式处理(这意味着如果我们可以“通过使用if......或类似的东西来预测这样的错误),我们应该避免使用“异常”,而只是返回一个像“false”这样的标志,用一个外部参数值告诉他/她详细的原因。
举个例子,我们可以这样创建一个类:
public class ValueReturnWithInfo<T>
{
public T Value{get;private set;}
public string errorMsg{get;private set;}
public ValueReturnWithInfo(T value,string errmsg)
{
Value = value;
errMsg = errmsg;
}
}
我们可以使用这种“多值返回”类来代替错误,这似乎是处理异常问题的一种更好、更礼貌的方式。
但是,请注意,如果一些错误不能如此容易地用"if"......(例如FileIO异常)描述(这取决于您的编程经验),则必须抛出异常。