哪种错误处理模型更强大?

Jas*_*son 8 vb.net error-handling

我在这两种错误处理模型之间徘徊:

  1. 为对象创建布尔值Error和字符串ErrorMessage属性.在对象的方法内部捕获所有异常,并使用来自调用者的条件逻辑传递消息,即:

    Dim o As New MyObject
    o.SomeMethod()
    If Not o.Error Then
        'Do stuff'
    Else
        Dim msg As String = o.ErrorMessage
        'do something with message'
    End If
    
    Run Code Online (Sandbox Code Playgroud)
  2. 在对象中抛出异常并使用Try Catch逻辑在外部处理它们:

    Dim o As New MyObject
    Try
       o.SomeMethod()      
       'Do stuff'
    Catch ex As Exception
        Dim msg As String = ex.ErrorMessage
        'do something with message'
    End Try
    
    Run Code Online (Sandbox Code Playgroud)

对我来说,这似乎是相同的代码量无论哪种方式,除非你拥有的属性代码ErrorErrorMessage属性.但是,您也可以在不检查异常的情况下判断何时发生错误.我应该选择哪种模式?

小智 7

我决定抛出异常,而不是使用错误/返回代码.我最近才非常努力.

抛出异常的首要原因是有可能忘记检查错误代码.如果您不检查它,那么您将在错误存在时继续工作.但有例外,如果您忘记处理它们,则异常将升至顶部并停止所有处理.发生这种情况比发生未知错误更好.

有关详细信息,请参阅Addison-Wesley的框架设计指南中的例外章节:可重用.NET库的约定,惯用法和模式,第二版.

Joel Spolsky实际上更喜欢错误/返回代码而不是例外,但很多人不同意他的看法.可以在这里找到Joel的支持返回代码的帖子.查看此博客文章和所有评论,并就此主题进行一些很好的讨论.


Jas*_*ams 1

我建议两者都使用。

为什么?

“使用适合工作的正确工具”

返回码的“问题”是人们经常忘记处理它们。然而,异常并不能解决这个问题!人们仍然不处理异常(他们没有意识到需要处理某个异常,他们假设堆栈上的某个人会处理它,或者他们使用 catch() 并消除所有错误)。

虽然未处理的返回代码可能意味着代码处于不稳定状态,但未处理的异常通常会导致程序崩溃。这是否更好?

虽然在编写代码时很容易识别返回代码,但通常不可能(或者只是非常耗时)确定您正在调用的方法可能引发哪些异常。这通常会导致许多非常糟糕的异常处理。

异常应该用于“错误”。困难就在于此。如果当您尝试打开文件时找不到该文件,这是“错误”还是“预期情况”?只有打电话的人知道。在任何地方使用异常本质上都会将每条状态信息提升为错误。

最终,错误处理是程序员必须做的事情。这个问题在返回码和异常中都存在。

因此,我使用返回码来传递状态信息(包括“警告”)和“严重错误”的异常。(是的,有时很难判断某物属于哪个类别)

.net 的示例案例:

Int32.Parse 抛出异常(即使它的异常都不是错误 - 由调用者来验证结果并自行决定结果是否有效)。必须将对它的每次调用都包含在 try/catch 中,这简直是一种痛苦(并且对性能造成影响)。如果您忘记使用 try/catch,简单的空白文本输入字段可能会使您的程序崩溃。

于是,Int32.TryParse()诞生了。这会执行相同的操作,但返回错误代码而不是异常,以便您可以简单地忽略错误(对于任何非法输入接受默认值 0)。在许多现实生活中,这比 Int32.Parse() 使用起来更干净、更快、更容易和更安全。

“TryParse”使用命名约定来让调用者清楚可能会发生错误,应该正确处理这些错误。另一种方法(强制程序员更好地处理错误)是将返回码放入 out 或 ref 参数中,以便调用者明确意识到需要处理返回的错误。

  • 《框架设计指南》第二版。给出了所有这些的指南,包括 TryParse 模式以及何时使用它。**强烈**推荐阅读。 (3认同)