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

时间:2009-10-10 13:20:53

标签: c# exception-handling

如果我有一个特定的例外情况,我预计它会发生; 并且为了处理它,例如我选择在其出现时显示错误消息,这样做会更好,为什么?

解释性代码:

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

或:

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

10 个答案:

答案 0 :(得分:12)

通常,异常用于指示异常情况 - 通常不会发生的情况,但您的程序仍需要优雅地处理(例如,文件无法访问或只读,网络连接断开)。正常的控制流,比如检查字典中的值,如果有一个具有相同效果而不使用异常的等效函数,则不应使用异常。

在代码中使用额外的try / catch语句也会降低其可读性,并且在代码块周围使用异常处理程序会对CLR造成某些限制,从而导致性能下降。

在您的示例中,如果预计字典将具有某个键值,我会执行类似

的操作
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

这比在元素访问中使用异常处理程序

要清楚得多

答案 1 :(得分:7)

都不是。

第二种选择比第一种更好。正如您所期望的那样,正常情况下,最好避免异常。例外情况应该优先用于特殊情况,即您无法轻易预测和测试的情况。

然而,最好的选择是TryGetValue方法,因为它同时检查和获取:

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

答案 2 :(得分:3)

第二种方法更好。抛出异常可能非常昂贵。

答案 3 :(得分:2)

第二种方法至少有三个原因更好:

1)更清楚。作为代码的读者,我希望有一个异常表明出现了问题,即使它已经处理完毕。

2)使用Visual Studio进行调试时,通常会中断所有异常,这使得处理总是抛出异常的代码变得有点烦人。

3)第二个版本更快,但效果非常小,除非你在一段时间关键的代码段中抛出许多异常。

答案 4 :(得分:2)

第二种方法可能更好。请记住,例外用于特殊情况。使用此原则来指导您的决定:

  • 如果您要求密钥作为应用程序不变量存在于字典中,则假设它存在并处理异常(如果不存在)。
  • 如果您的应用程序代码不要求条目中存在该条目,请先调用ContainsKey()

我的猜测是后者可能是正确的行动方案。

  

免责声明:我通常会避免在这里应将性能作为主要考虑因素的建议。只有在您证明自己遇到瓶颈后,才能让绩效影响您的决定!之前的任何事情都是premature optimization,并且会导致不必要的复杂应用程序代码。

答案 5 :(得分:1)

第二种方法更好,因为投掷和处理异常会影响性能。投掷率高于每秒100可能会显着影响性能 大多数应用程序。考虑Exceptions and Performance

答案 6 :(得分:1)

当您需要提供一种简单的方法来解决困难时,异常处理非常有用 - 它可以大大简化代码并减少角落错误的可能性。

在这种非常简单的情况下它没有什么优势,并且由于在这种情况下不应该使用它的性能损失。

答案 7 :(得分:0)

这完全取决于您的应用程序正在做什么以及具体代码正在做什么。

正如thecoop所说,异常应该用于特殊情况。作为插图,请写入文件。如果检查文件的存在会降低您的应用程序速度和/或文件的缺失是一个严重的问题,那么允许异常发生并陷阱。如果它不是那么关键或重新创建文件不是问题,那么先进行文件存在检查。

我看到它认为所有错误处理都应该通过异常进行(最近在Clean Code by Robert Martin),但我不同意。

答案 8 :(得分:0)

这在很大程度上取决于字典的意图。如果由于程序设计而很难找到密钥,那么您应该执行trygetvalue。但是,如果程序的设计是不能找到键是异常事件,则应使用异常处理程序方法。

答案 9 :(得分:-2)

提醒一下。这不是一个例外。 一个例外是听起来像“我的UNIX机器上没有/ etc”。 如果你的意思错了,你会写错误的代码如上所示。