Если я возвращаю значение внутри блока using в методе, утилизирует ли использование объекта перед возвращением? - PullRequest
4 голосов
/ 22 февраля 2010

Я просматриваю некоторый старый код C # .NET в приложении ASP.NET, чтобы убедиться, что все SqlConnections заключены в с использованием блоков.

Я знаю, что с использованием - это то же самое, что и try / finally , где он удаляет объект в finally независимо от того, происходит в try . Если у меня есть метод, который возвращает значение внутри с использованием , даже если выполнение покидает метод при возврате, он все равно вызывает .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 голосов
/ 22 февраля 2010

Да. Он избавится от вашего объекта. Это на самом деле вызовет проблему в вашем коде, поскольку возвращаемое 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...
    });
3 голосов
/ 22 февраля 2010

Да, он по-прежнему будет вызывать утилизацию.

Запустите это очень простое консольное приложение, чтобы проверить:

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