使用语句变体

时间:2012-08-28 17:17:28

标签: c# ado.net using

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

方法1:

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;
    }

方法2:

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;
    }

5 个答案:

答案 0 :(得分:5)

在第一个片段中,如果在创建IDisposable对象之后和开始使用之前发生任何异常,则将无法正确处理。在第二个实施中,没有这样的差距可能导致未发布的资源。

第一种方法可能出现的另一个问题是,您可以在处置后使用对象,这可能不会很好地结束。

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

答案 1 :(得分:1)

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

答案 2 :(得分:1)

如果您不使用,请不要处置您的objets没有托管,并且GC没有处置

GC只处理托管的对象,并且不管理sql连接所以你必须使用use dispose进行处理

答案 3 :(得分:1)

MSDN

  

您可以实例化资源对象,然后将变量传递给using语句,但这不是最佳做法。在这种情况下,在控制离开使用块之后,对象仍然在范围内,即使它可能不再能够访问其非托管资源。换句话说,它将不再完全初始化。如果您尝试使用using块之外的对象,则可能会导致抛出异常。因此,通常最好在using语句中实例化对象,并将其范围限制为使用块。

答案 4 :(得分:1)

第二个更好。请阅读http://msdn.microsoft.com/en-us/library/yh598w02.aspx上次评论。

第一个物体在处置后仍留在范围内。使用它然后不是好习惯。