【问题标题】:throw exception in the try block rather than catch block?在try块而不是catch块中抛出异常?
【发布时间】:2011-03-25 18:01:13
【问题描述】:

我在我们的项目中继承了如下所示的代码。它是一个类中的一个方法。

protected override bool Load()
{
    DataAccess.SomeEntity record;

    try
    {
        record = _repository.Get(t => t.ID.Equals(ID));

        if (record == null)
        {
            throw new InvalidOperationException("failed to initialize the object.");
        }
        else
        {
            this.ID = record.ID;
            // this.OtherProperty = record.SomeProperty;
            // etc
        } 
    }
    catch (Exception)
    {
        throw;
    }

    return true;
}

如果我随后从我的 UI 层调用此 Load 方法,我可能希望有一个 try catch 块来捕获因加载实例失败而导致的任何异常,例如InvalidOperationException,但上面的代码对我来说感觉不对。

InvalidOperationException 不会被 catch 语句吞掉吗?如果记录有效,该 catch 语句还将捕获 _repository.Get 的潜在问题,以及属性设置的潜在问题。

我想我可能应该通过添加更多try catch语句来分别处理Get操作和属性设置操作来重组它,或者添加更多处理不同异常的catch块,但我问了一位同事,他建议try catch是在这种情况下无关紧要,应完全删除,如下所示:

protected override bool Load()
{
    DataAccess.SomeEntity record;

    record = _repository.Get(t => t.ID.Equals(ID));

    if (record == null)
    {
        throw new InvalidOperationException("failed to initialize the object.");
    }
    else
    {
        this.ID = record.ID;
        // this.OtherProperty = record.SomeProperty;
        // etc
    } 

    return true;
}

我想要一些第二意见,我才刚刚开始对异常处理感兴趣,所以我想确保我按照最佳实践以正确的方式进行操作。

【问题讨论】:

  • 你的同事是对的。两个版本都一样,那为什么不减少代码呢?
  • 我建议将 throw 留在调试中 - 使用那段代码,您可以在 throw 上放置一个断点,然后然后检查异常(在即时窗口中使用$exception)。当您不确定到底会出现什么时,这样做很有用,并且正如其他海报所说的那样,否则它没有任何效果。

标签: c# exception-handling


【解决方案1】:

当你这样做时:

catch (Exception)
{
    throw;
}

您基本上没有处理异常。但是,这并不意味着您忽略它。 throw 语句会将异常向上传播到堆栈。为了干净可读的代码,您的最后一个示例要好得多。

【讨论】:

  • 真正拥有此代码的唯一原因(在throw 之前没有任何内容)是附加一个调试器(而不是全局的 Debug | Exception)。
  • 只捕获您知道需要捕获的异常。我通常会省略任何 try catch 块,除非我确切知道为什么在特定情况下需要它。将错误处理关闭,直到您绝对需要它 - 从应用程序最高点的单个全局错误处理程序开始 - 如果这是 asp.net,您可以挂钩应用程序错误事件并在那里记录错误,但我的观点是不要除非您知道为什么要添加它们并编写处理错误情况的代码而不是捕获它们,否则不要添加 try catch 块。此外,如果您删除了 try catch,也没有必要重新抛出错误
【解决方案2】:

如果您在调用方法 (Ithink) 中捕获异常,您应该只捕获您期望的异常。如果异常是 Load() 的问题,则向调用方法抛出一个新异常,并提供有关异常的更好信息。

【讨论】:

  • 制作“您可以处理的例外情况”。有很多例外,你可以预料到,但是,在代码的这一点上,没有任何用处。
【解决方案3】:

太棒了!你绝对是在正确的轨道上。先前的实现除了重新抛出不必要的异常之外什么也没做。您应该只处理您在业务层中预期的特定异常,否则让它们自然地沿着调用堆栈向上到 UI 层。

作为最佳实践,仅当您想添加一些额外的调试信息时才重新抛出异常,在这种情况下您需要定义自定义异常

【讨论】:

    【解决方案4】:

    异常catch 语句捕获,但由于它有一个throw 语句,它会抛出异常。这与您根本没有尝试/捕获具有相同的效果,因此您的同事建议将其排除在外是正确的。

    如果您实际上不以任何方式处理异常,那么添加异常处理代码没有多大意义。

    【讨论】:

      【解决方案5】:

      我同意您的同事的观点,您应该只捕获您知道需要捕获的异常。我通常会省略任何 try catch 块,除非我确切知道为什么在特定情况下需要它。这是因为如果您只是在所有内容周围放置 try catch 块,您往往会隐藏代码中的真正错误。将错误处理关闭,直到您绝对需要它 - 从应用程序最高点的单个全局错误处理程序开始 - 如果这是 asp.net,您可以挂钩应用程序错误事件并在那里记录错误,但我的观点是不要'不要添加 try catch 块,除非你知道为什么要添加它们并编写处理错误情况的代码而不是捕获它们。

      享受吧!

      【讨论】:

        猜你喜欢
        • 2011-03-18
        • 1970-01-01
        • 1970-01-01
        • 2012-02-20
        • 2020-12-16
        • 1970-01-01
        • 1970-01-01
        • 2021-11-17
        • 1970-01-01
        相关资源
        最近更新 更多