【问题标题】:Way to automatically see which functions can potentially return exception in c#在c#中自动查看哪些函数可能返回异常的方法
【发布时间】:2009-05-27 14:12:37
【问题描述】:

没有什么比在调试器中看到您的代码在一个异常的方法上崩溃而您没有尝试/捕获它更令人沮丧的了。

是否有一种简单的方法可以扫描您的源代码并标记所有可能引发异常的函数?

内置的视觉辅助是否有一些隐藏选项可以用特定颜色为这些功能着色?

谢谢

R

【问题讨论】:

  • dariom 与 A​​nders Hejlsberg 的采访的链接包含一个有趣的引语,准确地解释了我的观点:“但话虽如此,知道可以抛出哪些异常并拥有某种工具肯定具有巨大的价值检查。我认为我们不能构建硬性和快速的规则,它要么是编译器错误,要么不是编译器错误。但我认为我们当然可以使用检测可疑代码的分析工具做很多事情,包括未捕获的异常和点把那些潜在的漏洞给你”
  • FxCop 就是这样一个工具,但它不会警告你未捕获的异常.. 恰恰相反:blogs.msdn.com/fxcop/archive/2006/06/14/631923.aspx
  • 您链接的文章也讨论了一般异常子句:catch(Exception e) 并尝试对其进行一般处理。他们强调指定您要处理的异常并让其余的流程流动。我完全同意,但我的观点仍然存在:请指出我错过了哪些异常并且实际上没有处理。异常猎人工具似乎完全符合我的需要。明天我会玩一下它,看看它做了什么样的分析,然后在这里报告。

标签: c# exception detection


【解决方案1】:

除了最琐碎的代码之外的所有代码都可能引发异常(至少内存不足)。最好是防御性地编写代码,至少使用全局 try/catch,而不是尝试微观管理哪些代码段将引发或不会引发异常。

【讨论】:

  • 按照这些思路,同行评审代码。即使是无害的行,例如 Int32 x = x / y;可能会引发 DivideByZero 异常。最佳实践是验证方法的所有输入,以验证它们是否在可接受的范围内;代码分析通常会告诉你什么。
  • 你们说我应该在每一行代码中都放一个try/catch,然后处理所有可能发生的事情。这将给出一个丑陋的代码块。让我们假设不会发生诸如内存异常之类的灾难性事情(在这种情况下,您最好记录事件并让它消失),我只是在编码时想知道哪些方法可能会产生(记录的)异常。 Int32.Parse(string) 就是一个很好的例子。如果 vis studio 以某种方式说:小心,可能会抛出:Null 异常或格式异常,那就太好了。我可以处理它
  • @NotMe, Int32 x = x / y;永远不会返回 DivByZero 异常。为什么?因为它不会编译。您正在尝试在声明 x 之前使用它。整数除法也不太常见,因为结果被截断。值得注意的是 var z = 1 / 0.0;不会抛出异常。结果是 double.PositiveInfinity。
【解决方案2】:

不,没有办法自动执行此操作,也没有获得方法抛出的所有可能异常的列表的好方法。以下是一些原因

  1. 考虑隐式抛出的异常,例如 StackOverflowException 可以随时从任何方法抛出。您必须假设 CLR 中的任何方法都可以抛出这些类型的异常
  2. 反射和/或委托可以隐藏在特定方法中调用的实际代码,因此您无法检查方法的所有可能代码路径。
  3. 这需要检查 IL 与元数据。
  4. 在 .Net 中,不需要记录 API 显式抛出的异常

【讨论】:

  • 1) 这些你不想在每行的基础上处理......这些类型的异常你全局记录并重新启动你的程序(取决于应用程序)2)我只是引用 .Net 库调用,帮助文件中列出的例外 3) 或只是一个包含所有库调用及其例外的工具 4) 我只指 .Net 库调用。这已经很棒了。
【解决方案3】:

我认为 redgate 为这个“异常猎手”提供了一些工具 他们在试用后收取费用。

http://www.red-gate.com/products/Exception_Hunter/index.htm

【讨论】:

  • +1 代表 RedGate,但要为销售电话做好准备!我认为真正的价值往往会被所有可能的例外所淹没,但仍然是一个不错的工具。
  • 异常猎手已经停止。有没有其他选择?
【解决方案4】:

正如其他人所说,我不确定您是否会在 C# 中找到一种万无一失的方法,因为它不支持检查异常。

顺便说一句,这让我想起了与 Anders Hejlsberg 讨论“The trouble with Checked Exceptions”的采访。我并不是要煽动检查异常,而是建议您阅读 Ander 的 C# 异常设计背后的基本原理以及处理异常的建议方法:集中式异常处理。

【讨论】:

  • 查看对我的主要问题的评论,看看安德斯在这次采访中实际上同意我的观点,即指出“被遗忘的异常处理程序”的工具会非常好。我将浏览建议的工具列表,然后发布最相关的工具。
【解决方案5】:

我认为 resharper 会为您提供有关异常的提示。但是由于 C# 不支持检查异常的原因,有办法确定异常。也许像 NDepend 之类的代码分析工具支持这一点。

【讨论】:

    【解决方案6】:

    一切都可能引发异常。查看 MSDN 以获取方法可以抛出的异常列表。

    【讨论】:

    • 是的...检查使用的每个功能的 msdn 很乏味...因此我的问题;^)
    【解决方案7】:

    所有非空方法都可以以一种或另一种形式抛出异常。如果您担心自己生成的异常,您可以从智能感知中显示它们,就像框架方法通过 XML 文档一样,如下所示:

    /// <summary>  
    /// I seem to have written a method to do a thing.
    /// </summary>  
    /// <exception cref="System.Exception">An unfortunate failure.</exception>
    public void DoSomething()
    {
       /* ... */
    }
    

    【讨论】:

    • Intellisense 现在没有显示任何异常...如何为 .Net 库调用启用此功能?
    【解决方案8】:

    任何代码都可能导致异常,您的工作是尝试并预测这一点!

    有许多第三方工具可以帮助发现一些常见错误,例如 fxcop 和重构等工具可以提出建议。

    目前已经完成了一些工作,可以帮助您发现潜在的异常。查看 PEX,它可以帮助为您的函数生成测试:research.microsoft.com/en-us/projects/Pex/(发布时链接似乎已关闭)

    另一个令人兴奋的领域是代码合同(在 .net 4 中出现/作为规范#提供)。代码契约允许您编写指定必须满足的条件的语句。这些可以在你的函数被调用之前和之后,你也可以声明不变量。条件可能像 value != null 这样简单。然后在编译和运行时分析这些条件,以检查没有代码路径违反它们。

    【讨论】:

    • 我确实希望能预料到这一点……但如果 Visual Studio 能帮我一点忙就好了。为每个 .Net 调用打开 MSDN 至少可以说是乏味的
    【解决方案9】:

    正如其他人所说,您应该假设每一行代码都可以引发异常,除非您已经证明它不能。更好的问题是,“你打算怎么做?”

    一般来说,您根本不应该捕获任何异常。

    当然,其他一切都是该规则的例外。捕获异常以便记录它是有意义的(如果您的环境不为您这样做,就像 ASP.NET 那样)。捕获异常以便将其替换为提供有关上下文的更多详细信息的另一个异常是有意义的:

    public int GetConfiguredInteger(string name) {
        string s = null;
        try {
            s = GetStringFromConfigFile(name);
        }
        catch (IOException ex) {
            throw new Exception(String.Format(
                "Error in configuration file foo.config when processing {0}", name),
                ex);
        }
        return int.Parse(s);
    }
    

    如果您没有告诉调用者,调用者不可能知道 IOException 是由配置文件引起的。还要注意我如何忽略与文件 I/O 无关的所有异常。特别要注意 int.Parse 甚至不在 try/catch 块内。

    还有少量其他此类异常,但捕获异常的基本思想是:除非不这样做会更糟,否则不要这样做。

    【讨论】:

    • 我确实想处理异常,因为不处理它们意味着我的应用程序失败。一个很好的例子是在进行网络请求时使用它。当远程服务器返回“错误请求”html 错误时,会在异常中返回给我。如果人们没有预料到这一点,你的程序就会死掉。对于这些情况,工具(或智能感知颜色)可以很好地指出这些可能的例外情况。
    • 没有。当异常发生时,您的应用程序已经“失败”。如果您的应用程序依赖于成功的网络请求,那么失败的请求意味着您的应用程序失败。在这种情况下,如果您的应用程序是 WinForms,您确实希望在最终调用 Web 请求的事件处理程序中捕获异常,然后记录异常并可能显示 MessageBox。但是应用程序已经失败,对此您无能为力。失败 == “不能按照用户的要求做”。
    • 应用程序不必失败。这完全取决于应用程序。假设我有远程日志记录,而 webrequest 是我记录某些内容的方式。如果这失败了,我的整个程序不需要关闭/崩溃,也不需要向用户报告某些内容。但是,我确实想提前发现这个方法可以抛出异常,这样我就可以优雅地处理它(并自行决定应用程序是否需要死掉或做其他事情,或者只是忽略它并继续)。
    • Every 方法可以抛出异常,如前所述。而是更广泛地设计。例如,是否允许异常跨层;如何与日志记录和其他诊断等集成。不要像使用 Java 那样专注于捕获每个异常。
    【解决方案10】:

    Exception Finder 中有一个反射器添加,它将显示方法可能引发的异常。我没用过,但在 .Net 用户组会议上看到了一个例子。

    【讨论】:

      【解决方案11】:

      有一个工具可以做到这一点。您可以下载试用版,看看您是否喜欢它。我真的不认为这有必要,但如果你在一家公司工作并且他们会为此付出代价,你可能想要调查一下。就像之前所说的那样,有太多可能的例外被提出。查看Excpetion Hunter

      【讨论】:

        【解决方案12】:

        少数人提到的Exception Hunter 是一个很好的工具来帮助解决这个问题。我不知道它是否与&lt;exception&gt; XML-Doc 注释有关联,以便您可以强制记录代码引发的异常。

        【讨论】:

          【解决方案13】:

          我发现打破外部 catch 块并挖掘到异常发生的实际点更令人沮丧。

          大多数情况下,如果抛出异常并且我没有预料到它,我发现了一个错误,如果它没有被一些无所事事的异常处理混淆,那么解决它会更容易。

          编辑: 由于您的示例实际上是一个很好的示例,因此我仍然不相信这样的工具会对您有所帮助。会有很多可能的异常,实际上每一行代码都可能抛出,你很难找到“有趣”的异常。

          【讨论】:

          • 我不想做任何异常处理程序。我只是希望能够事先浏览一下代码,并让一些工具指出最明显被遗忘的 try catch 块
          • 你有一个实际的例子吗?
          • 我遇到的最后一个异常是 http 服务器返回了“400 错误请求”。这导致该行出现异常: HttpWebResponse response = (HttpWebResponse) request.EndGetResponse(result);仔细想想,这可能是显而易见的,但如果有工具向我指出此函数可能引发潜在异常(除了 stackoverflow/内存不足异常),那就太好了。
          猜你喜欢
          • 1970-01-01
          • 2017-07-16
          • 1970-01-01
          • 2017-12-11
          • 2013-01-07
          • 2015-03-05
          • 1970-01-01
          • 2020-09-17
          • 1970-01-01
          相关资源
          最近更新 更多