我正在尝试找到编写有关检查无效值的代码的正确方法。在我的情况下,无效的值为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"原则,因为看起来我们只是将问题推迟到对象生命周期的后期阶段?
答案 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();
}
支票可能隐藏或嵌套,难以找到。