重复参数检查功能

时间:2010-07-14 10:30:21

标签: c# data-integrity

我经常调用层次结构,因为所有方法都需要相同的参数。如果我不想把它们放在实例级别(类的成员),那么我总是问我是否有意义检查每种方法中它们的有效性。

例如:

public void MethodA(object o){
   if(null == o){
      throw new ArgumentNullException("o");
   }
   // Do some thing unrelated to o

   MethodB(o);

   // Do some thing unrelated to o

}

public void MethodB(object o){
   if(null == o){
      throw new ArgumentNullException("o");
   }
   // Do something with o
}

如果Method A使用参数,那么它清楚,我必须检查那里的有效性以及MethdoB。但只要MethodA不再对o执行操作而不是将其提交给MethodB,在MethodA中检查有效性也是一种好习惯。

MethodA中检查的优势可能是被调用方调用的方法中抛出异常,这很好,但是有必要吗?调用堆栈也会说明这一点。也许它有意义的公共,内部,受保护但不是私人方法?

我以空值检查为例,但索引验证或范围验证也属于自我问题,但我认为由于存在冗余代码的危险,因此存在局限性。你觉得怎么样?

更新

通过AakashM的回答,我看到我的确很精确。 MethodA不仅会调用MethodB,还会调查与o无关的其他内容。我添加了一个例子来澄清这一点。谢谢AakashM。

3 个答案:

答案 0 :(得分:9)

史蒂夫麦康奈尔的“代码完成”谈论了“街垒”这一概念 - 一道防御墙,其中数据不受信任,其中数据受信任。想要进入街垒的数据必须经过验证过程,但在街垒内,数据可以通过验证码自由移动。

如果你可以在你的项目中强加这么多的结构和分层,并坚持下去,它确实会使内部的路障代码有更少的仪式和更多的本质。但是只需要一种方法来控制路障就会出错。

在您的示例中,MethodBpublic。这意味着您没有自动将来保证MethodA将成为其唯一的调用者 - 因此我会说它的验证代码应该保留。但是,如果该类为private,则可以进行删除它的参数。

至于MethodA,如果它实际上 ,而不是调用MethodB,则它不应该存在。如果它是未来扩展的存根,并且在某些时候它会对o执行某些操作,那么它的验证代码也应该保留。

答案 1 :(得分:1)

我认为你应该确保产生输入值的一次(来电者的责任)。如果该类仅由内部客户端使用,则此方法有效。如果它是公共API的一部分,那么你无法逃避检查,但你可能想要将它们分解,如其他答案所示。

出于测试目的,您还可以在两种方法中使用Debug.Assert(o != null),并且将从发布代码中删除检查,如果性能是个问题

答案 2 :(得分:1)

我不认为参数验证是“冗余代码”。您需要保护所有外部入口点。如果您有一个private方法,以便通过时间流知道它的所有参数都将有效,那么您可能有一个案例,但public(甚至{{} 1}})你真的没有的方法。