检查方法中的无效值

时间:2012-03-22 08:07:49

标签: c# oop

我正在尝试找到编写有关检查无效值的代码的正确方法。在我的情况下,无效的值为null。在SO中有其他问题的是它们属于特定情况,我对更通用的解决方案感兴趣。

我有这样的代码:

public class SomeClass
{
    private readonly object m_internallyUsedObject;
    private ThirdPartyObject m_user; // Third party object.

    public SomeClass(object internallyUsedObject)
    {
        m_internallyUsedObject = internallyUsedObject; // We just want to ensure that the object will remain the same throught the life time of SomeClass object.
        m_user = new ThirdPartyObject(); // This object is not yet needed here.
    }

    public void DoSomething()
    {
        m_user.DoSomethingElse(m_internallyUsedObject); // Now we're using it and we are not sure whether null value is tolerated.
    }
}

由于我们在构造函数中使用internallyUsedObject,我们可能知道该对象的语义以及如何使用它。另一方面,我们只是在调用期间将此对象转发给第三方对象。 无论值是SomeClass还是<{1}},我们的null对象都可以正常工作。

现在,问题是我们不知道null是否始终适用于ThirdPartyObject - 它可能在一个版本中有效(在这种情况下,可以省略null检查并且不要在另一个人工作。

如果我们的班级可以处理它,我们就不应该关心检查null。但是当我编写代码文档时,我想告诉用户我们自己的类的行为和期望。

正如我上面提到的,在特定的第三方对象的版本中,这个简单的检查可能没有用,甚至无效:

if (internallyUsedObject == null)
{
    throw new ArgumentNullException("internallyUsedObject");
}

根据OOP,当我们不打算直接使用它时,从构造函数中的代码中取internallyUsedObject是否有效?它是否违反了"fail fast"原则,因为看起来我们只是将问题推迟到对象生命周期的后期阶段?

1 个答案:

答案 0 :(得分:0)

作为一项规则,我倾向于使用您在第二个代码块中描述的方法,但结合合理的检查分组。我的意思是,应该执行特定方法的某些检查,并在执行逻辑之前采取措施,例如

public void MyMethod(MyObject input) {

    // 1. perhaps security checks, if an in method security is required
    if(security.AccessLevel < requiredLevel)
        throw new CustomSecurityException("Insufficent Access");

    // 2. data checks
    if(input.Property == null)
        throw new ArgumentNullException("Input didn't contain the value I wanted");

    if(input.Property2 < someImportantLevel)
        throw new CustomBLException("Input didn't meet required level for something");

    // 3. perform BL
    // ...do whatever

}

这可能并不理想,并且通常像方法属性之类的东西可以用于安全方面,但在我们的相当多的应用程序中,这似乎是一个合理的检查分组。你知道所有的检查都是预先完成的,而不是像这样的冗长的块:

if(input != null) {
    //do logic
} else {
    throw new Exception();
}

支票可能隐藏或嵌套,难以找到。