我目前正在编写一个小框架,将供公司内的其他开发人员在内部使用.

我想提供良好的Intellisense信息,但我不确定是否有how个可以记录抛出的异常.

在以下示例中:

public void MyMethod1()
{
    MyMethod2();

    // also may throw InvalidOperationException
}

public void MyMethod2()
{
    System.IO.File.Open(somepath...); // this may throw FileNotFoundException

    // also may throw DivideByZeroException
}

我知道记录异常的标记是:

/// <exception cref="SomeException">when things go wrong.</exception>

我不明白的是如何记录代码called by MyMethod1()引发的异常?

  • 我是否应该记录由MyMethod2()引发的异常
  • 我应该记录File.Open()抛出的异常吗?

记录可能的异常的最佳方式是什么?

推荐答案

您应该记录代码可能引发的每个异常,包括您可能调用的任何方法中的异常.

如果列表有点大,可能需要创建自己的异常类型.捕获方法中可能遇到的所有异常,将它们包装在异常中,然后抛出该异常.

您可能希望这样做的另一个地方是,如果您的方法位于API的表面上.就像外观将多个接口简化为单个接口一样,您的API应该将多个异常简化为单个异常.使调用者更容易使用您的代码.


为了回答安德鲁的一些担忧(从 comments 中),有三种类型的例外:你不知道的例外,你知道但不能做任何事情的例外,以及你知道并可以做一些事情的例外.

那些你不知道的你想放手.这是快速失败的原理——与其让应用程序进入一种可能最终 destruct 数据的状态,不如让它崩溃.崩溃将告诉你发生了什么以及原因,这可能有助于将异常从"你不知道的"列表中移除.

那些你知道但却无能为力的异常,比如OutOfMemoryExceptions.在极端情况下,您可能希望处理这样的异常,但除非您有一些非常显著的需求,否则您会将它们视为第一类——让它们go 吧.您是否需要记录这些例外情况?在每一个新创建对象的方法上记录OOM看起来都很愚蠢.

您知道并且可以做些什么的那些就是您应该记录和包装的那些.

你可以再找到guidelines on exception handling here.

.net相关问答推荐

MSBuild:CopyToOutputDirectory不会将本机DLL复制到输出

Dotnet 反射:使用 F# 中的out参数调用 MethodInfo 上的调用

C#/.NET + VisualStudio,命名空间问题

如何将 Assembly.CodeBase 转换为 C# 中的文件系统路径?

在 WP7 中将 List 转换为 ObservableCollection

.NET 的 Visual Studio 调试器提示和技巧

.Include() 与 .Load() 在 EntityFramework 中的性能

是否可以模拟 .NET HttpWebResponse?

将双精度转换为带有 N 个小数的字符串,点作为小数分隔符,并且没有千位分隔符

在 C# 中与块等效?

System.Speech.Recognition 和 Microsoft.Speech.Recognition 有什么区别?

如何允许程序集(单元测试)访问另一个程序集的内部属性?

从 OpenFileDialog 路径/文件名中提取路径

Dispatcher.CurrentDispatcher 与 Application.Current.Dispatcher

beforefieldinit 标志有什么作用?

判断对象列表是否包含具有特定值的属性

铸造:(NewType)与对象作为NewType

System.IO.IOException:使用 System.IO.Path.GetTempFileName() 时文件存在 - 解决方案?

当它被抛出和捕获时,不要在那个异常处停止调试器

如何将两个 List 相互比较?