【问题标题】:C# Try/Catch/Finally [closed]C# Try/Catch/Finally [关闭]
【发布时间】:2013-12-04 14:33:40
【问题描述】:

我大部分时间都被教导要始终从我的代码中删除 try/catch/finally 块。这背后的原因对我来说总是有意义的(如果你的应用程序按照它应该的方式工作,你不需要防止错误),但同时有很多事情会导致错误,而不是由于糟糕编码;服务器打嗝,图形似乎永远不会在无缘无故失败时失败,等等。我还被告知这些块会降低性能,我个人在使用它们时没有注意到,但我想这可能是案子。基本上我要做的是; Try/Catch/Finally 一个糟糕的整体想法,或者在某些情况下是另一个好的想法,当过度使用糟糕的代码以保持应用程序运行时不好,对测试有好处/对生产不好?只是想要一些意见。

【问题讨论】:

  • 像所有语言功能一样,try/catch 可以用于好坏。通常,避免使用 catch 进行控制流。我认为“终于”不属于您所说的类别。在某些情况下,确保适当的资源清理是绝对必要的。我不认为做出笼统的“不使用它”决定是明智的。您需要评估每种情况以找到解决问题的最佳方法。有时,try/catch 就是一个答案。
  • 经验法则非常简单...如果可能发生异常,请将其包装在异常处理程序中。不仅仅是catch异常,而是以某种方式有意义地handle它。不过,这都是猜测,没有具体的例子。你能用你被告知不正确的 try/catch/finally 使用的特定实例来更新问题吗?
  • 示例:File.ReadAllText 在文件处于访问状态时抛出异常 - 如果不使用 try/catch,您将如何处理?
  • @Shaharyar 我很确定 catch 块对性能的影响很小(如果有的话)。由于堆栈卷绕/展开,引发异常是导致性能下降的原因。

标签: c# coding-style try-catch standards


【解决方案1】:

有些情况你真的无法避免Try/Catch

考虑这样一种情况,您希望用户输入一些要输入到数据库表中的数据。用户的输入也包括主键,现在如果一些用户输入了重复的主键,你会得到一个异常。你现在要做什么 ?让系统崩溃或处理异常并向用户显示用户友好的消息以输入不同/独特的内容。

考虑一个例子,假设您想检查某个 URL 是否有效且可用,您可能需要一些方法,例如:(take from here)

private bool IfURLExists(string url)
{
    try
    {
        HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
        request.Method = "HEAD";
        HttpWebResponse response = request.GetResponse() as HttpWebResponse;
        return (response.StatusCode == HttpStatusCode.OK);
    }
    catch //may catch specific WebException First
    {
        return false;
    }
}

如果没有try/catch,上述方法将无法工作。

try/finally 的另一个重要用法是与using 语句一起使用,using 与实现IDisposable 接口并转换为try/finally 块的对象一起使用,因此如果发生异常,它将确保处置非托管资源.

如果你想对它们做一些有用的事情,通常只捕获那些异常,否则让exception bubble up

【讨论】:

  • 在这种情况下,参数将是执行错误检查并确保在插入新记录之前密钥不存在。不只是等待 SQL 异常返回。
  • 当然不是一个很好的例子,但想法才是最重要的。
  • @Volearix 和确定性失败,这只是一个例子......
  • @Volearix:事先检查将被转储,因为它可能会在检查和执行之间发生变化。并且序列化所有内容以便您可以事先正确检查并确保它不会更改,这真的很愚蠢。
  • @deterministicFail,删除了示例并添加了一些新示例。
【解决方案2】:

如果以周到的方式使用 try/catch/finally 块,绝对没有错。

作为开发人员,您甚至无法想象客户的想法与您有多么不同,或者您的系统将如何与不同的系统交互或对您没有想到的输入做出反应。

唯一的规则是:不要滥用。

【讨论】:

  • 实际上,我会删除有关用户输入的部分。您不应该通过抛出/捕获异常来验证用户输入 - 无效输入并不是真正的异常
  • 我会说这取决于输入。在某些情况下,您可能不得不解析格式不正确的文档;用户输入不仅仅是用户必须填写的表单字段。
【解决方案3】:

完全不清楚为什么那个人想要完全摆脱try/catch/finally

我什至不明白为什么 finally 块出现在画面中?如果没有 finally 你将如何可靠地清理资源?

c# 语言提供了using 语句,它实际上是在try/finally 结构上实现的语法糖,那么这是错误的吗?还是辱骂?你能实现一个没有try/finally的using块吗?

foreach 使用try/finally,还有很多你真正需要它的地方。

典型示例:考虑“套接字编程”,在处理套接字时如何避免捕获SocketExceptionIOException?那实用吗?当然不。需要时应使用它们。

结论:try/catch/finally 应该以应有的方式使用。你不应该吃异常,这并不意味着你必须让异常终止你的进程。你必须处理它。

【讨论】:

    【解决方案4】:

    一个基本规则是在您可以处理的时间和地点捕获异常。如果您无法处理它们,请让它们通过。对程序进程中未捕获的任何内容的最终处理可能是记录并向用户显示错误消息。

    【讨论】:

      【解决方案5】:

      你应该只捕获你可以处理的异常,其他的应该冒泡。 你绝对不能捕获像NullReferenceExceptionArgumentOutOfRangeException 这样的异常。这些是错误,捕获会在您的代码中隐藏这些错误。

      关于这个话题的文章:Vexing exceptions

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-09-30
        • 2019-01-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-10-26
        • 2011-08-27
        • 2014-11-27
        相关资源
        最近更新 更多