说我有以下方法:
void UpdateContentMethodA(Int32[] src, Int32[] dst)
{
for(int i=0; i<src.Length; i++)
{
dst[i] = src[i];
}
}
void UpdateContentMethodB(Int32[] src, Int32[] dst)
{
if(src == null || dst == null) throw new System.ArgumentNullException();
if(src.Length != dst.Length) throw new System.IndexOutOfRangeException();
for(int i=0; i<src.Length; i++)
{
dst[i] = src[i];
}
}
我是编写methodB还是认为methodA没问题?
编辑:抱歉,我对写这些方法很懒:
这些方法仅用于演示目的,实际代码使用不同的数据类型,异常实例在其构造函数中传递有用的信息。
我了解到,优秀的程序员应该编写好的代码,即使它仅用于演示目的。你们真棒,谢谢!
答案 0 :(得分:9)
我个人会将代码更改为:
void UpdateContentMethodB(Int32[] src, Int32[] dst)
{
if (src == null) throw new ArgumentNullException("src");
if (dst == null) throw new ArgumentNullException("dst");
if(src.Length != dst.Length) throw new ArgumentException("src and dst must be the same length", "src");
答案 1 :(得分:2)
根据面向公众的方法的.Net指南,您应该进行明确的参数验证,因此UpdateContentMethodB
是首选方法。
然而在第二种情况下,我不会使用IndexOutOfRangeException
。相反,我会扔ArgumentInvalidException
。
答案 2 :(得分:1)
你应该明确地抛出异常。
此外,you should pass the parameter name to ArgumentNullException
。
答案 3 :(得分:1)
正确的实施:
void UpdateContentMethodB(Int32[] src, Int32[] dst)
{
if(src == null)
throw new ArgumentNullException("src");
if(src == null)
throw new ArgumentNullException("dst");
if(src.Length != dst.Length)
throw new InvalidOperationException("Source length does not match destination length...blah blah blah");
for(int i=0; i<src.Length; i++)
{
dst[i] = src[i];
}
}
答案 4 :(得分:1)
鉴于上面的例子,我会选择方法A,因为你的检查几乎没有增加价值。一般建议尽可能早地失败,从这个意义上来说,方法B将是最好的解决方案。
另一方面,如果你向异常提供有意义的错误消息(例如通知调用者src或dst是否为null,或者它们的长度是多少),那么它们确实会增加值,我会选择方法B.
您可能希望查看Microsoft Code Contracts,它允许您表达方法的前置条件和后置条件。
答案 5 :(得分:0)
通常认为抛出明确的异常比依靠能够解决后续失败和堆栈检查中发生的事情更好。
但是,你没有提供一个非常精彩的例子。 ArgumentNullException应该采用null的参数的名称,并且IndexOutOfRange实际上不是“两个长度必须相同但不是。”的正确例外。
我会抛出可能因为长度不匹配而抛出ArgumentException,并确保将足够的信息传递给构造,以便明白出现了什么问题。
答案 6 :(得分:0)
方法B如果您希望这可能发生并且您需要更多信息来进行调试。方法A,如果您认为这些参数是安全传入方法的。