0

我发现我的代码库包含各种数据访问代码,我以两种不同的方式使用 using 语句。如果有的话,哪种方法更好,这两种方法是否不同?没有在 using 语句中实例化 SqlConnection 和 SqlCommand 可能会出现什么问题?忽略明显的不一致问题。

方法一:

public int SampleScalar(string query, CommandType queryType, SqlParameter[] parameters)
    {
        int returnValue = 0;
        SqlConnection objConn = new SqlConnection(ConnString);
        SqlCommand objCmd = new SqlCommand(query, objConn);
        objCmd.CommandType = queryType;

        if (parameters.Length > 0)
            objCmd.Parameters.AddRange(parameters);

        using (objConn)
        {
            using (objCmd)
            {
                objConn.Open();
                try
                {
                    returnValue = (int)objCmd.ExecuteScalar();
                }
                catch (SqlException e)
                {
                    Errors.handleSqlException(e, objCmd);
                    throw;
                }
            }
        }
        return returnValue;
    }

方法二:

public int SampleScalar2(string query, CommandType queryType, SqlParameter[] parameters)
    {
        int returnValue = 0;
        using (SqlConnection objConn = new SqlConnection(ConnString))
        {
            using (SqlCommand objCmd = new SqlCommand(query, objConn))
            {
                objConn.Open();
                objCmd.CommandType = queryType;

                if (parameters.Length > 0)
                    objCmd.Parameters.AddRange(parameters);
                try
                {
                    returnValue = (int)objCmd.ExecuteScalar();
                }
                catch (SqlException e)
                {
                    Errors.handleSqlException(e, objCmd);
                    throw;
                }
            }
        }
        return returnValue;
    }
4

5 回答 5

5

在第一个片段中,如果在创建对象之后和开始使用之前发生任何异常,IDisposable则不会正确处理它。使用第二个实现,没有可能导致未释放资源的这种差距。

第一种方法可能出现的另一个问题是,您可以在处理对象后使用它,这不太可能结束。

您可能会确保不会发生异常,也许您不会。一般来说,我永远不会使用第一种方法,因为我不相信自己(或其他任何人)永远不会在那个不受保护的空间里犯错。如果不出意外,我将需要花费时间和精力仔细查看,以确保不会出错。使用这种不太安全的方法也不会真正获得任何好处。

于 2012-08-28T17:20:28.770 回答
1

我总是选择第二种方法。更容易阅读和理解在给定块的末尾处理了哪些对象。它还会阻止您使用已处置的对象。

于 2012-08-28T17:19:29.700 回答
1

如果您不使用 using,则不要处置您的对象,不托管,GC 不处置

GC dispose 只管理对象,不管理 sql 连接,所以你必须 dispose,最后使用 use dispose

于 2012-08-28T17:19:48.140 回答
1

根据MSDN

您可以实例化资源对象,然后将变量传递给 using 语句,但这不是最佳实践。在这种情况下,对象在控制离开 using 块后仍保留在范围内,即使它可能不再有权访问其非托管资源。换句话说,它将不再被完全初始化。如果您尝试在 using 块之外使用该对象,则可能会引发异常。出于这个原因,通常最好在 using 语句中实例化对象并将其范围限制在 using 块中。

于 2012-08-28T17:21:21.007 回答
1

第二个更好。请阅读http://msdn.microsoft.com/en-us/library/yh598w02.aspx最后一句话。

在第一个对象被处理后,它仍然在范围内。然后使用它不是一个好习惯。

于 2012-08-28T17:23:14.100 回答