函数中的重复参数检查
我经常拥有调用层次结构,因为所有方法都需要相同的参数。如果我不想将它们放在实例级别(类的成员),那么我总是问我是否有意义在每种方法中检查它们的有效性。函数中的重复参数检查
例如:
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
也检查的优势可能是异常抛出被调用者调用的方法,这很好,但它是否有必要?调用堆栈也会说明这一点。也许它的意义在公共,内部,受保护但不是私人方法?
我以空检查为例,但索引验证或范围验证属于自我问题,但我认为由于冗余代码的危险而存在限制。你怎么看?
UPDATE
通过我已经看到了,我是有点精确AakashM的答案。 MethodA
不仅呼叫MethodB
,它也做其他事情,但不涉及o
。我添加了一个例子来澄清这一点。谢谢AakashM。
史蒂夫麦康奈尔的代码完整谈论'路障'的概念 - 一个防御墙外的数据是不可信的,内部的数据是值得信赖的。想要进入路障的数据必须经过验证过程,但是在路障中,数据可以随意通过验证码自由移动。
如果你可以在你的项目中加入这样的构造和分层,并且坚持下去,它确实会使内部代码的代码更少,更精髓。但是只需要一种方法就可以调用路障来防止出错。
在你的例子中,MethodB
是public
。这意味着你没有自动的未来保证MethodA
将成为它的唯一调用者 - 因此我会说它的验证码应该保留。但是,如果它是private
,那么您可以为删除它做一个参数。
至于MethodA
,如果它实际上没有没有多于致电MethodB
,它应该不存在。如果它是未来扩展的存根,并且在某些时候它将与o
做些什么,那么它的验证代码也应该保留。
我认为你应该确保它一旦产生输入值(调用者的责任)。如果该类仅由内部客户端使用,这将起作用。如果它是公共API的一部分,那么您不能退出支票,但您可能需要将它们分解,正如其他答案中所述。
出于测试目的,您也可以在两种方法中使用Debug.Assert(o != null)
,如果性能问题,检查将从发布代码中删除。
我不认为参数验证“冗余代码”。您需要保护所有外部入口点。如果你有一个private
的方法,这样你就知道时间流程到了它的所有参数都会有效,那么你可能有一个例子,但是对于public
(甚至protected
)方法你真的不会。
产生输入值的地方 - 在调用者意味着什么?我想要写我的例子的例子是,方法A和B都可以从类的外部访问,并且它的合法调用其中的一个(MethodA执行相同,比MethodB稍微多一点) – HCL 2010-07-14 11:01:53
是的。看我的编辑。 – Mau 2010-07-14 11:21:16