2

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

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
}

在前面的代码片段中,已检查连接是否为空或关闭了 3 次。这对我来说似乎有点矫枉过正——有时该方法的 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?
    }
}
4

2 回答 2

3

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

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

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

于 2013-07-15T08:54:55.173 回答
1

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

于 2013-07-15T08:58:56.543 回答