如何在c#/ .net中记录抛出的异常

Arn*_*kas 136 .net c# documentation intellisense

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

我想提供良好的Intellisense信息,但我不知道如何记录抛出的异常.

在以下示例中:

public void MyMethod1()
{
    MyMethod2();

    // also may throw InvalidOperationException
}

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

    // also may throw DivideByZeroException
}
Run Code Online (Sandbox Code Playgroud)

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

/// <exception cref="SomeException">when things go wrong.</exception>
Run Code Online (Sandbox Code Playgroud)

我不明白的是如何记录被调用的 代码引发的异常MyMethod1()

  • 我应该记录引发的异常吗? MyMethod2()
  • 我应该记录引发的异常File.Open()吗?

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

小智 108

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

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

你可能想要这样做的另一个地方是你的方法是在你的API面前.就像外观将多个接口简化为单个接口一样,您的API应将多个异常简化为单个异常.使呼叫者更容易使用您的代码.


为了回答安德鲁的一些顾虑(来自评论),有三种类型的例外:你不了解的,你知道的和不能做的事,以及你所知道的并且可以做些什么.

那些你不了解的人想要放手.它是快速失败的原则 - 更好地使您的应用程序崩溃,而不是进入可能最终破坏您的数据的状态.崩溃将告诉你发生了什么以及为什么,这可能有助于将这个异常移出"你不知道的"列表.

你知道但无法做任何事情的是像OutOfMemoryExceptions这样的例外.在极端情况下,您可能希望处理这样的异常,但除非您有一些非常出色的要求,否则您将它们视为第一类 - 让我们去吧.你必须记录这些例外吗?对于新建对象的每一种方法,你都会看起来非常愚蠢地记录OOM.

你知道并可以做些什么的是你应该记录和包装的.

您可以在此处找到有关异常处理的更多指南.

  • @Tymek我认为你的观点可能是,如果你可以做些什么,为什么不对它做点什么而不是重新抛出它并记录它呢?说"你知道的那些_client_代码可以做些什么"可能会更加准确.这消除了矛盾,因为这些是文档的理想例外. (5认同)
  • 我必须承认这听起来不太实际.我无法想象我可以调用的任何代码可以抛出多少潜在的异常,还有像OutOfMemoryException这样的东西,你不想捕获和包装. (3认同)
  • 你的回答是好的,但实际上是两个相互矛盾的答案."记录你的代码可能引发的每一个异常"和"你应该知道并且可以做些什么的是你应该记录的那些". (3认同)
  • @Tymek:不.上半部分回答了"我应该如何记录异常"的问题.第二部分指出了"我应该记录哪些例外"的明显答案.第一个并不意味着您记录可能发生的每个异常.有些人太字面意思,需要下半年. (2认同)

chi*_*s42 93

您应该使用标准的xml文档.

/// <exception cref="InvalidOperationException">Why it's thrown.</exception>
/// <exception cref="FileNotFoundException">Why it's thrown.</exception>
/// <exception cref="DivideByZeroException">Why it's thrown.</exception>
public void MyMethod1()
{
    MyMethod2();
    // ... other stuff here
}

/// <exception cref="FileNotFoundException">Why it's thrown.</exception>
/// <exception cref="DivideByZeroException">Why it's thrown.</exception>
public void MyMethod2()
{
    System.IO.File.Open(somepath...);
}

/// <exception cref="FileNotFoundException">Why it's thrown.</exception>
public void MyMethod3()
{
    try
    {
        MyMethod2();
    }
    catch (DivideByZeroException ex)
    {
        Trace.Warning("We tried to divide by zero, but we can continue.");
    }
}
Run Code Online (Sandbox Code Playgroud)

这样做的价值在于您提供了可能发生的已知异常的文档.如果您使用visual studio,则可以在intellisense中使用此文档,并且可以在以后提醒您(或其他人)您可以预期的异常.

您希望指定特定的异常类型,因为您可能能够处理一种类型的异常,而其他类型是严重问题的结果,无法更正.

  • @ShiranGinige你的经历是错的. (7认同)

Iga*_*nik 35

您可以使用几个出色的加载项来简化文档编制过程.其中之一是GhostDoc,它是Visual Studio的免费插件,可生成XML-doc注释.此外,如果您使用ReSharper,请查看针对ReSharper 的优秀Agent Johnson插件,该插件添加了为抛出异常生成XML注释的选项.

更新:似乎Agen Johnson不适用于R#8,结账特别是ReSharper作为替代品......

第1步:GhostDoc生成XML注释(Ctrl-Shift-D),而ReSharper的Agent Johnson插件也建议记录异常:

步骤1

第2步:使用ReSharper的快捷键(Alt-Enter)添加异常文档:

第2步http://i41.tinypic.com/osdhm

希望有帮助:)


Dan*_*fer 10

根据我的理解,使用<exception>元素的意图是在装饰方法时使用它,而不是例外:

/// <summary>Does something!</summary>
/// <exception cref="DidNothingException">Thrown if nothing is actually done.</exception>
public void DoSomething()
{
// There be logic here
}
Run Code Online (Sandbox Code Playgroud)

可以通过其他方法抛出的异常应该在这些方法中捕获,处理和记录.可能会记录.NET可能抛出的异常,或者您自己的代码显式抛出的异常.

至于获得更具体的信息,也许您可​​以捕获并抛出自己的自定义异常?