何时检查功能/方法参数?

时间:2009-05-28 12:49:28

标签: function methods

在编写小函数时,我经常遇到一些参数被赋予一个函数的情况,该函数本身只将它们传递给不同的小函数来实现其目的。

例如(C#-ish Syntax):

public void FunctionA(object param)
{
    DoA(param);
    DoB(param);
    DoC(param);
    // etc.
}

private void DoA(object param)
{
    DoD(param);
}

private void DoD(object param)
{
    // Error if param == null
    param.DoX();
}

所以这些参数不是在被调用的函数中使用,而是在执行该工作的小函数的深处“某处”。

那么什么时候最好检查我的param-Object是否为空?

签入功能A时:

临: - 通过使用其他方法没有任何开销,最后这些方法无效,因为对象为空。

缺点: - 我的语法很棒很好的功能A被丑陋的验证码弄脏了。

仅在使用param-object时进行检查:

临: - 我的语法精彩功能AA值得高兴阅读:)

缺点: - 通过调用方法会产生开销,因为param-object为null,所以这些方法无效。 - 目前我没有考虑进一步的缺点。

6 个答案:

答案 0 :(得分:6)

总是把它放在尽可能远的调用堆栈中,这样如果你以后重构代码和其他东西调用除DoA以外的DoD,你就可以进行检查,而不必重新进行参数检查。在大多数情况下,小的空检查和可能的一些额外的方法调用的开销将是微不足道的,并且多做几次检查不是你应该担心的事情。

答案 1 :(得分:4)

除非您认为绝大部分时间值都可能为空,否则我会将验证放在DoD()中。如果你将它放在FunctionA()中,那么当你决定FunctionB()也需要使用DoD()时,你将不得不重复验证代码。对我来说,额外的开销不值得重复自己。

答案 2 :(得分:1)

作为指导原则,我习惯于通过该方法检查所使用的每个参数,甚至包括我自己的私有变量。因此,我只会在你的国防部方法中检查是否为零。

你可能想看看Bertrand Meyers Design By Contract咒语。

答案 3 :(得分:1)

提前失败。除非部分结果优于完全没有结果,否则只要代码可以检测到存在问题,就应该停止执行。当结果下游将成为无效或缺少参数时,为什么代码应该运行多个方法?

如果可以单独调用下游方法,则可以通过调用已经建议的常用验证来处理验证。

答案 4 :(得分:0)

始终检查所有内容:)来自嵌入式系统编码库的深层内容,这就是我使用的方法:

public void FunctionA(object param)
{
    assert(param != null && param.canDoX());
    DoA(param);
    DoB(param);
    DoC(param);
    // etc.
}

private void DoA(object param)
{
    assert(param != null && param.canDoX());
    DoD(param);
}

private void DoD(object param)
{
    assert(param != null && param.canDoX());
    if ( param != null )
        param.DoX();
    else
        // Signal error, for instance by throwing a runtime exception
        // This error-handling is then verified by a unit test that 
        // uses a release build of the code.
}

为了解决这个问题,显而易见的解决方案是将验证分解为单独的验证器函数。使用C风格的预处理器,或者只是坚持使用断言,从发布版本中排除这种“偏执”验证应该是微不足道的。

答案 5 :(得分:0)

传递有效参数是调用者的责任。在这种情况下:

if(param != null)
{
  FunctionA(param);
}