【问题标题】:How often should I check the validity of the arguments?我应该多久检查一次论点的有效性?
【发布时间】:2013-07-15 08:46:50
【问题描述】:

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

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
}

在之前的sn-p中,已经检查了连接是否为null或关闭了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?
    }
}

【问题讨论】:

    标签: c# arguments


    【解决方案1】:

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

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

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        猜你喜欢
        • 2011-05-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-04-04
        • 2014-07-07
        • 1970-01-01
        • 1970-01-01
        • 2015-08-09
        相关资源
        最近更新 更多