C#异常文档指南

时间:2015-01-22 07:04:22

标签: c#

我正在努力的API变得非常庞大,现在我正在研究一些多线程的东西,所以我想确保我知道在任何给定点都可能发生的所有异常。我知道C#没有检查你必须用每个方法声明的异常,比如Java,但我想我会在每个方法的文档中都这样做。

考虑以下非常简单的例子:

/// <exception cref="System.DivideByZeroException">oh no, divide by zero.</exception>
int someMethod(int a, int b)
{
    return a / b; //this might throw DivideByZeroException
}

//clearly this method can never throw a DivideByZeroException
int someOtherMethod(int a)
{
    return someMethod(a, 2);
}

我是否将DivideByZeroException标记添加到&#34; someOtherMethod&#34;?

当然这只是一个非常简单的例子,真正的代码更复杂,但有时我知道一个异常,即子方法抛出永远不会发生。不是因为我抓住它,而是因为我总是将有效的参数传递给它。

如果我想要有关例外的文档,那么我有3个选项:

1)这样的例外行为永远不会发生,并且不会将标签添加到文档中(因为它永远不会,并且我有单元测试来支持它)。

2)为我知道永远不会发生的异常添加异常标记。

3)尝试捕捉并忽略,以确保它永远不会发生,因此我可以将其从具有良好意识的异常列表中删除。

我最喜欢选项1,但对此有什么指导吗?

3 个答案:

答案 0 :(得分:1)

我从未见过有关此问题的任何指导方针,但开发人员大多是合乎逻辑的人,并希望在文档中看到可能发生的异常,而不会看到那些不能发生的异常。只是合乎逻辑,它通常比遵循指南要好得多(当然这也很重要)。

答案 1 :(得分:0)

以下是一般规则,在设计API时,请确保您对所有公共方法都有XML注释,以便想要使用您的API的开发人员确切知道您的方法所做的事情。

对于你的情况,你应该为someOtherMethod添加注释,这可能会抛出DivideByZeroException。 Visual Studio不会帮助您识别某些内部方法可以抛出异常。您必须手动跟踪此内容。

这是一个代码示例

public void MethodA(object someObject, int a, int b)
{
    if (someObject == null)
        throw new ArgumentNullException();

    MethodB(a, b);
    MethodC(b, a); // Possibility of OverflowException,
}

public void MethodAA(object someObject, int a, int b)
{
    if (someObject == null)
        throw new ArgumentNullException();

    MethodB(a, b);
    MethodC(b, b); // No Possibility of OverflowException,
}

internal int MethodB(int a, int b)
{
    return a/b; // This can throw DivideByZeroException
}

public int MethodC(int a, int b)
{
    retirm a - b; // This can cause Overflow exception.
}

现在MethodA XML注释应该有ArgumentNullException,DivideByZeroException和OverFlowException。因为所有情况都是可能的。但是对于MethodC,你应该只有OverFlowException。

但是对于方法AA,你永远不会得到OverFlowException。因此,对于MethodAA,您应该为ArgumentNullException,DivideByZeroException提供XML注释。

答案 2 :(得分:0)

考虑一个更普遍的情况,你会抛出一个与内部调用中引发的异常不同的异常(为简单起见,下面是无意义的例子):

public class Foo
{
    int b;

    public int GetBar(int a)
    {
        try
        {
            return helperGetBar(a, b);
        }
        catch (DivideByZeroException e)
        {
            throw new InvalidOperationException("...", e); //object has not been initialized correctly.
        } 
    }

    static int helperGetBar(int a, int b)
    {
        return a/b; //Can raise DivideByZeroExpection
    }
}

为什么要将GetBar记录为DivideByZeroException,而根本不可能?

您只需提交InvalidOperationException文档,因为这是该方法可以引发的唯一异常。如果该方法不能引发任何异常,则无需记录。