我是否应该从这种方法中抛出异常?

时间:2009-08-30 01:13:38

标签: c# .net exception extension-methods

我正在方法中执行一些参数验证,并在必要时抛出异常。我是否需要手动抛出这种类型的异常?只要调用者被包装在try..catch块中,无论手动检查是否到位,都会抛出类似的异常。

    public static Int16 ToInt16(this byte[] value, int startIndex, bool isBigEndian) {

        // are these exceptions necessary?
        if (value == null) {
            throw new ArgumentNullException("value");
        }

        if ((startIndex + 1) >= value.Length) {
            throw new ArgumentOutOfRangeException("startIndex");
        }    

        return (isBigEndian)
            ? (Int16)((value[startIndex] << 8) | value[startIndex + 1])
            : (Int16)((value[startIndex + 1] << 8) | value[startIndex]);
    }

这是一种扩展方法,用于将数组中的2个字节转换为Int16,并可以切换Big Endian或Little Endian转换。

5 个答案:

答案 0 :(得分:9)

这里抛出异常的价值在于,不是获得null deref异常,而是获得一个参数异常,最重要的是告诉你无效的参数。该异常也更明确地指向原因,而不是通用的null deref,它可以是任何东西。

鉴于这是一个已经是一个间接层的扩展方法,我认为完成并包含异常可能更有用。特别是考虑到你已经写好了,但即使是政策问题。如果它不是扩展方法,我可以去任何一种方式。我也可以使用一个断言,取决于代码的埋藏方式。

我目前不知道但是在.Net 1.1和1.0框架中,JIT编译器永远不会内联一个抛出它的调用。为了避免这种情况,通常意味着创建一个不同的方法来抛出异常本身。

顺便说一句,你有一个错误的startIndex + 1&gt; value.Length;它应该是&gt; =而不是。

答案 1 :(得分:5)

根据“类库设计指南”,您应该验证类型的公共成员的所有参数。 http://msdn.microsoft.com/en-us/library/8ey5ey87(VS.71).aspx


更新:较新版本:http://msdn.microsoft.com/en-us/library/ms229007.aspx

答案 2 :(得分:3)

如果您查看DotNET Framework代码(例如,使用Reflector),那么您会发现MS人员会手动抛出这些异常。

如果您制作的SDK会被第三方程序员大量使用,我建议您至少在顶级函数上抛出ArgumentNullExceptions。

答案 3 :(得分:3)

我的意见是你应该抛出异常。我的想法是,您似乎正在构建可重用的代码,该代码可能成为其他程序或该程序其他部分中使用的库的一部分。虽然您可能在当前代码中使用了适当的异常处理,但无法保证您或将来使用此方法的其他人会进行适当的异常处理。另一个考虑因素是,在维护中,此方法的实现可能会发生变化,您必须考虑不能立即捕获问题和抛出异常会带来什么影响。我认为你上面的代码是可以的,除了我通常提供一个更具描述性的信息,只是更明确一点(当然这是我的偏好和你正在做的事情仍然传达问题)。

答案 4 :(得分:3)

每当你编写一个公共方法时,你都应该把它当成黑盒子,因为其他程序员会这样做。

如果您有两种方法, MethodA(int i) MethodB(int i),这更容易理解?

  • MethodA(1000)会抛出ArgumentOutOfRangeException
  • MethodB(1000)会抛出IndexOutOfRangeException
无需打开方法代码即可轻松修复

MethodA 。由于与参数无关的原因, MethodB 可能会抛出该异常,因此您必须调试该方法以确定出现了什么问题。