2009-08-30 91 views
4

我在一个方法中执行一些参数验证并在必要时抛出异常。我是否需要手动抛出这种类型的异常?只要调用者被包装在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的一种方式来切换大端或小字节序变换的扩展方法。

+0

请注意,您正在使用ParamName创建两个例外,请尝试考虑一条有用的消息。 – 2009-08-30 08:51:01

+0

全部,感谢您的评论。似乎一致认为例外应该保留。我先接受了彼得的回答,他先找到了我的错字,然后找到了我的错字。 – user158485 2009-08-30 20:30:24

回答

9

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

鉴于这是一种扩展方法,它已经是一种间接的方式,我认为它可能更加有用,包括例外。特别是鉴于你显然已经写了它,但即使是作为一个政策的问题。如果这不是一种扩展方法,我可以采取任何方式。取决于代码的隐藏程度,我可能也会使用assert。

我目前还不知道,但在.Net 1.1和1.0框架中,JIT编译器不会内联一个有投入的调用。为了避免这种情况,通常意味着要创建一个不同的方法来引发异常。

顺便说一句,你有一个错误与startIndex + 1> value.Length;它应该是> =代替。

3

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

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

3

我的观点是,你应该抛出一个异常。我的想法是,您似乎正在构建可重用的代码,可能成为其他程序或此程序其他部分中使用的库的一部分。虽然您可能正在使用当前代码中的适当异常处理,但不保证您或将来使用此方法的其他人将执行适当的异常处理。另一个考虑是在维护中,这种方法的实施可能会发生变化,您必须考虑不会立即引发问题并抛出异常的含义。我认为你上面的代码是可以的,除了我通常会提供一个更明确的信息来更明确一些(当然这是我的偏好,你正在做什么仍然会传达这个问题)。

3

任何你正在写一个公共方法的时候,你应该把它像一个黑盒子,因为其他程序员。

如果你有两个方法,治法(int i)以方法b(int i)以,这是容易理解?

  • 治法(1000)抛出ArgumentOutOfRangeException
  • 方法b(1000)抛出IndexOutOfRangeException

方法a更容易固定,而不必打开代码的方法。 方法B可能因为与参数无关的原因而引发该异常,所以您必须调试该方法以确定发生了什么问题。

+0

这种想法的一个问题是'ArgumentOutOfRangeException'也可能由'MethodA'调用的方法抛出,原因与传递给'methodA'的参数无关,'IndexOutOfRangeException'更能描述实际问题。真正需要的是区分与渗透方法无关的渗透的例外,但没有标准的约定。 – supercat 2014-05-03 02:37:09

相关问题