在哪里验证方法的参数?

时间:2012-06-17 18:46:58

标签: c# .net exception-handling

我想知道代码验证方法的参数在哪里 - 以及多久 - 。

在下面的示例类(.dll库)中,您认为最好的方法是什么?假设我想验证,某些对象不能是null(但它可以是方法正常运行所需的任何其他验证)。最好只在第1点检查一次,在用户可用的公共方法中,以及后来的“信任自己”,在其他私有方法中,它不会为空,或者更好的是有点偏执并且每个都检查一下时间它将被使用(在点2. 3.和4.)

在使用对象之前检查它(在第2,3,4点)将来保护我,如果我决定使用这些私有方法更改类中的某些内容,并“忘记”传递有效对象。如果我将来添加一些新的公共方法,我也不必记住验证。另一方面 - 它一遍又一遍地检查相同的条件。或许你还有其他建议吗?

public class MyClass()
{
    public MyClass()
    {
    }

    public void ProcessObject(SomeObject obj)
    {
        //1. if (obj == null) throw new ArgumentException("You must provide valid object.");

        DoSomething(obj);
        DoMore(obj);
        DoSomethingElse(obj);
    }

    private void DoSomething(SomeObject obj)
    {
        //2. if (obj == null) throw new ArgumenException("You must provide valid object.");
        //do something with obj...
    }

    private void DoMore(SomeObject obj)
    {
        //3. if (obj == null) throw new ArgumentException("You must provide valid object.");
        //do something with obj...
    }

    private void DoSomethingElse(SomeObject obj)
    {
        //4. if (obj == null) throw new ArgumentException("You must provide valid object.");
        //do something with obj..
    }
}  

3 个答案:

答案 0 :(得分:12)

如果它是您要让其他开发人员使用的API,那么在您的每个方法上,您确实应该抛出ArgumentExceptionArgumentNullException

如果它是其他开发人员不会直接与之交互的内部类或方法,我会使用Debug.Assert,因此在调试模式下,您将获得其他调试信息,并且在发布模式下,它会被删除并且您会收到所有这些参数检查无处不在的性能优势。

答案 1 :(得分:5)

在一个好的软件设计方法中,需要彼此独立。 您必须能够以任何顺序使用它们并相互分离。所以是的,你必须一遍又一遍地检查所有方法中的相同条件。

修改 我会使用CodeContract与Pre-Condition检查obj不为null。因为这似乎是方法正常工作的先决条件。

答案 2 :(得分:3)

每个公共方法都应验证其输入。

如果您只是传递以前验证的对象,私有方法可以依赖IMHO验证类中的其他公共方法。由于私有方法被封装在类中,因此验证的责任保留在类中。

但是,如果你有一个私有方法需要一些计算参数(而不是那些传递给公共方法的参数),那么应该有额外的验证。

您的单元测试将测试该类的公共界面,如果您的SomeObjectnull,如果您的验证仅在ProcessObject,则它们将失败。在这种情况下,我不会在私有方法中复制验证。