简体   繁体   English

这在异常处理中是一种更好的做法吗?

[英]which is a better practice at exception handling?

if I have a specific exception that I expect when it is going to occur; 如果我有一个特定的例外,我预计它会发生; and to handle it for example I chose to display an error message upon its occurance, which would be better to do, and why? 并且为了处理它,例如我选择在其出现时显示错误消息,这样做会更好,为什么?

Explanatory code: 解释性代码:

try
{
    string result = dictionary[key];
}
catch (KeyNotFoundException e) 
{ 
    //display error
}

or: 要么:

if(!dictionary.ContainsKey(key))
{
    //display error
}

Generally, exceptions are used to indicate exceptional conditions - something that would not normally occur, but your program still needs to handle gracefully (eg a file being inaccessible or readonly, a network connection going down). 通常,异常用于指示异常情况 - 通常不会发生的情况,但您的程序仍需要优雅地处理(例如,文件无法访问或只读,网络连接断开)。 Normal control flow, like checking for a value in a dictionary, should not use exceptions if there is an equivalent function that has the same effect without using exceptions. 正常控制流(如检查字典中的值)如果存在具有相同效果而不使用异常的等效函数,则不应使用异常。

Having extra try/catch statements in the code also makes it less readable, and having exception handlers around a block of code puts certain limitations on the CLR that can cause worse performance. 在代码中使用额外的try / catch语句也会降低其可读性,并且在代码块周围使用异常处理程序会对CLR造成某些限制,从而导致性能下降。

In your example, if it is expected that the dictionary will have a certain key value, I would do something like 在您的示例中,如果预期字典将具有某个键值,我会做类似的事情

string result;
if (!dictionary.TryGetValue(key, out result)
{
    // display error
    return;   // or throw a specific exception if it really is a fatal error
}

// continue normal processing

This is a lot clearer than just having an exception handler round an element access 这比在元素访问中使用异常处理程序要清楚得多

Neither. 都不是。

The second option is better than the first. 第二种选择比第一种更好。 As you expect this to happen normally, it's better to avoid the exception. 正如您所期望的那样,正常情况下,最好避免异常。 Exceptions should preferrably only be used for exceptional situations, ie something that you can't easily predict and test for. 例外情况应该优先用于特殊情况,即您无法轻易预测和测试的情况。

The best option however is the TryGetValue method, as it does both check and fetch: 然而,最好的选择是TryGetValue方法,因为它同时检查和获取:

if (dictionary.TryGetValue(key, out result)) {
   // use the result
} else {
   // display error
}

The second approuch is better. 第二个approuch更好。 Exception throwing can be very expensive. 抛出异常可能非常昂贵。

The second approach is better for at least 3 reasons: 第二种方法至少有三个原因:

1) It is clearer. 1)更清楚。 As a reader of your code, I expect an exception to indicate that something has gone wrong, even if it's handled. 作为代码的读者,我希望有一个异常表明出现了问题,即使它已经处理完毕。

2) When debugging with Visual Studio it's common to break on all exceptions, that makes it mildly annoying to deal with code which always throws an exception. 2)使用Visual Studio进行调试时,通常会中断所有异常,这使得处理始终抛出异常的代码变得有点烦人。

3) The second version is faster, but the effect is very small unless you are throwing many exceptions a second in a time-critical piece of code. 3)第二个版本更快,但效果非常小,除非你在时间关键的代码段中抛出许多异常。

The second approach is probably better. 第二种方法可能更好。 Remember that exceptions are used for exceptional circumstances . 请记住, 异常用于特殊情况 Use this principle to guide your decision: 使用此原则来指导您的决定:

  • If you require that the key exists in the dictionary as an application invariant, then assume that it is there and deal with the exception if it isn't there. 如果您要求密钥作为应用程序不变量存在于字典中,那么假设它存在并处理异常(如果不存在)。
  • If your application code doesn't require that the entry exist in the dictionary, then call ContainsKey() first. 如果您的应用程序代码不要求条目中存在该条目,则首先调用ContainsKey()

My guess is that the latter is probably the correct course of action. 我的猜测是,后者可能是正确的行动方案。

Disclaimer: I generally eschew the advice that performance should be the primary consideration here. 免责声明:我一般都认为表现应该是这里的首要考虑因素。 Only let performance impact your decision once you have proven that you have a bottleneck! 只有在您证明自己遇到瓶颈后,才能让绩效影响您的决定! Anything before that is premature optimization and will lead to unnecessarily complication application code. 之前的任何事情都是过早优化 ,并将导致不必要的复杂应用程序代码。

The second approach is better because throwing and hanlding exception has its performance hit. 第二种方法更好,因为投掷和处理异常会影响性能。 Throw rates above 100 per second are likely to noticeably impact the perfor- mance of most applications. 每秒100次以上的投掷率可能会显着影响大多数应用程序的性能。 Consider Exceptions and Performance . 考虑异常和性能

Exception handling is most useful when you need to provide an easy way out of a difficult situation - it can greatly simplify the code and decrease the potential for corner-case bugs. 当您需要在困难的情况下提供简单的方法时,异常处理是最有用的 - 它可以大大简化代码并减少角落错误的可能性。

It offers little advantage in very simple situations like this, and due to its performance penalty should not be used in such cases. 它在这种非常简单的情况下几乎没有优势,并且由于其性能损失不应该在这种情况下使用。

It all depends on what you're application is doing and what the specific code is doing. 这完全取决于您的应用程序正在做什么以及具体代码正在做什么。

As thecoop says exceptions should be used for exceptional conditions. 正如thecoop所说,异常应该用于特殊情况。 As an illustration take writing to a file. 作为插图,请写入文件。 If checking for the existence of the file would slow your application down and/or the absence of the file is a serious problem then allow the exception to occur and trap that. 如果检查文件的存在会降低您的应用程序速度和/或文件的缺失是一个严重的问题,那么允许异常发生并陷阱。 If it's not so critical or recreating the file isn't a problem then do the file existence check first. 如果它不是那么关键或重新创建文件不是问题,那么先进行文件存在检查。

I've seen it argued that all error handling should be done via exceptions (most recently in Clean Code by Robert Martin ) but I don't agree. 我已经看到它认为所有的错误处理都应该通过异常进行(最近在Robert Martin的Clean Code中 ),但我不同意。

It depends greatly on what the dictionary is meant to do. 这在很大程度上取决于字典的意图。 If there is a high chance that the key will not be found because of program design, then you should do the trygetvalue. 如果由于程序设计而很难找到密钥,那么您应该执行trygetvalue。 However, if the design of your program is such that not finding the key is an exceptional event, you should use the exception handler method. 但是,如果程序的设计是不能找到键是异常事件,则应使用异常处理程序方法。

Just a reminder. 只是提醒。 It is not an exception. 这不是一个例外。 An exception is something sounds like "no /etc on my UNIX machine". 一个例外是听起来像“我的UNIX机器上没有/ etc”。 If you get wrong sense, you'll write wrong code shown as above. 如果你错了,你会写错误的代码如上所示。

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

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