如果我在方法中的using块内返回一个值,那么在返回之前是否会使用dispose对象?

4
我正在审查一个ASP.NET应用程序中的一些旧C#.NET代码,确保所有的SqlConnections都被包含在using块中。
我知道usingtry / finally相同,在finally中处理对象的释放,无论在try中发生什么。如果我有一个在using中返回值的方法,即使执行离开该方法时返回,它是否仍会在返回之前/期间/之后调用我的对象上的.Dispose()
public static SqlCommand getSqlCommand(string strSql, string strConnect){
    using (SqlConnection con = new SqlConnection(strConnect))
    {
        con.Open();
        SqlCommand cmd = GetSqlCommand();
        cmd.Connection = con;
        cmd.CommandText = strSql;
        return cmd;
    }
}

更新: 接受的答案是我认为最好回答了我的问题,但请注意这个答案指出了这段代码的愚蠢之处,即我正在返回使用已释放连接的命令! :P

2个回答

9
是的。它将处理您的对象。这实际上会在您的代码中引起问题,因为返回的SqlCommand依赖于SqlConnection,而在控制流返回到调用方之前,该对象将被处理。
但是,您可以使用委托来解决此问题。一个好的模式是像这样重写您的方法:
public static SqlCommand ProcessSqlCommand(string strSql, string strConnect, Action<SqlCommand> processingMethod)
{ 
    using (SqlConnection con = new SqlConnection(strConnect)) 
    { 
        con.Open(); 
        SqlCommand cmd = GetSqlCommand(); 
        cmd.Connection = con; 
        cmd.CommandText = strSql; 
        processingMethod(cmd); 
    } 
} 

您可以这样调用它:
ProcessSqlCommand(sqlStr, connectStr, (cmd) =>
    {
        // Process the cmd results here...
    });

哇,好发现!谢谢。这个方法在很少的地方使用(而且很老),所以我可能会将其删除并在需要它们的地方创建命令。 - adambox

3

是的,它仍然会调用dispose方法。

运行这个非常简单的控制台应用程序来验证:

   class Program
    {
        static void Main(string[] args)
        {
            TestMethod();
            Console.ReadLine();
        }

        static string TestMethod()
        {
            using (new Me())
            {
                return "Yes";
            }
        }
    }

    class Me : IDisposable
    {
        #region IDisposable Members

        public void Dispose()
        {
            Console.WriteLine("Disposed");
        }

        #endregion
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接