2

可能重复:
如果我在方法的 using 块内返回一个值,那么 using 在返回之前会处理该对象吗?

我有这个代码(简化):

bool method1()
{
      using (OleDbConnection con = new OleDbConnection(connString))
            {
                bool b = false;

                try
                {
                    con.Open();
                    b = true;

                }
                catch (Exception)
                {
                    b = false;
                }
                finally
                {
                    con.Close();
                    return b;
                }                
            }
}

我在“使用”语句的右大括号之前返回。我的对象“con”是否仍然被 Disposed?使用以下代码更好吗?:

bool method1()
{
      bool b = false;
      using (OleDbConnection con = new OleDbConnection(connString))
            {
                try
                {
                    con.Open();
                    b = true;

                }
                catch (Exception)
                {
                    b = false;
                }
                finally
                {
                    con.Close();                    
                }                
            }

        return b;
}
4

5 回答 5

4

using语句的全部意义在于它自动处理对象,即使从 using 块中抛出未处理的异常也是如此。

因此,一旦您的代码退出 using 块,无论是返回还是其他方式,我们都会处理正在“使用”的对象。

于 2013-01-12T14:35:54.070 回答
2

由于 .NET 自动处理对象的魔法,在 using 语句期间返回是完全安全的。整个想法是您不必考虑如何退出 using 块,您只知道当您离开它时,对象将被正确处理。因此,您的示例可以简化为:

bool method1()
{
    using (OleDbConnection con = new OleDbConnection(connString))
        {
            try
            {
                con.Open();
                return true;
            }
            catch (Exception)
            {
                return false;
            }          
    }
}

con.Close() 可以被删除,也可以被处理自动调用。

如果您想了解幕后发生的事情,请查看此内容。

于 2013-01-12T14:44:21.240 回答
1

在第一个示例中,您设置了一个临时变量并将其返回。

关于 finally 中的返回:编译后发生的事情是你分支到方法的末尾,然后返回一个临时变量。

例如,结果完全相同。为了清楚起见,我个人更喜欢第一个,因为它更准确地类似于发生的事情。

于 2013-01-12T14:43:16.607 回答
1

两个代码段之间没有区别;conobject 将在两个示例中被处理。

于 2013-01-12T14:35:38.767 回答
0

using扩展为更复杂的附加if语句,例如

OleDbConnection con = new OleDbConnection(connString)
try
{
    con.Open();
}
finally
{
    // Check for a null resource.
    if (con != null)
        // Call the object's Dispose method.
        ((IDisposable)con).Dispose();
}  

因此,在您的示例中,您可能会NullReferenceException进入 finally 块。

所以如果你想返回操作和Dispose和对象的状态,我建议使用这个代码片段

using(OleDbConnection con = new OleDbConnection(connString))
{
    try
    {
        con.Open();
        return true;
    }catch(OleDbException ex)
    {
        //log error
        return false;
    }
}
于 2013-01-12T14:44:28.467 回答