我应该多久检查一下论证的有效性?

时间:2013-07-15 08:46:51

标签: c# arguments

我经常遇到类似的架构问题。人们应该多久检查输入参数的有效性?让我们检查以下示例(不关心代码的正确性或可编译性):

public void DoSth()
{
    context.DbPerform((SQLiteConnection connection) =>
        {
            // *** 1 ***
            if (connection == null)
                throw new ArgumentNullException("connection");
            if (!connection.IsOpen)
                connection.Open();

            try
            {
                Data.Insert(data, connection);
            }
            finally
            {
                connection.Close();
            }
        });
}

// ----

public static void Insert(Data data, SQLiteConnection connection)
{
    // *** 2 ***

    if (data == null)
        throw new ArgumentNullException("data");
    if (connection == null)
        throw new ArgumentNullException("connection");

    if (!connection.IsOpen)
        connection.Open();

    try
    {
        using (var cmd = connection.CreateCommand())
        {
            cmd.CommandText = SQL.InsertData;

            FillParameters(data, connection, cmd);

            cmd.ExecuteNonQuery();
        }
    }
    finally
    {
        connection.Close();
    }
}

// ----

public static void FillParameters(Data data,
    SQLiteConnection connection,
    SQLiteCommand cmd)
{
     // *** 3 ***
     if (connection == null)
         throw new ArgumentNullException("connection");

     // And so on, you get the idea
}

在上一个代码段中,已检查连接为空或关闭三次。这对我来说似乎有点过分 - 有时方法的50%是安全检查。我觉得不需要那么多的安全检查,但另一方面,其他人总是可以使用这些方法,我不能确定他是否通过了有效的参数。

所以我的问题是:

  • 应该多久写一次关于传递参数的安全检查?
  • 可以使用哪些技术来保持安全级别,但不经常进行安全检查?
  • 检查无效输入时我应该多么偏执?考虑另一个例子:
class C
{
    private Obj obj;

    public C (Obj newObj)
    {
        if (newObj == null)
            throw new ArgumentNullException("newObj");

        obj = newObj;
    }

    public void DoSth()
    {
        // Should I check, whether obj is not null?
    }
}

2 个答案:

答案 0 :(得分:3)

关于第一个示例,Insert()中的检查是个好主意,因为Insert()public。它可以从没有进行检查的另一个上下文中调用。

通常,始终在公共接口点进行验证。这有助于使代码松散耦合并可重用。

每一层(层,方法)都有自己的要求。因此,在该任务开始时验证您执行某项任务所需的内容。

答案 1 :(得分:1)

我同意Henk。此外,请尝试考虑Visual Studio的Code Contracts扩展,它提供了一种在代码中指定前置条件,后置条件和对象不变量的方法:http://visualstudiogallery.msdn.microsoft.com/1ec7db13-3363-46c9-851f-1ce455f66970。它强制执行一种非常一致的方法来保护您的代码,并且“Pex”工具可用于根据合同自动生成测试。