在“using(实现iDisposable的对象)”语句中返回一个方法是正确的吗?

时间:2013-01-12 14:31:57

标签: c# .net idisposable using

  

可能重复:
  If I return a value inside a using block in a method, does the using dispose of the object before the return?

我有这个代码(简称):

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”无论如何都会被废弃吗?是否更好地使用以下代码?:

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

5 个答案:

答案 0 :(得分:4)

using语句的重点在于它会自动处理对象,即使从使用块中抛出未处理的异常也是如此。

因此,一旦您的代码退出使用区块,无论它是否返回,那么该对象将被使用'我们处置了。

答案 1 :(得分:2)

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

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

con.Close()可以被移除,也可以通过处置自动调用。

如果你想看看幕后会发生什么,请看this

答案 2 :(得分:1)

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

答案 3 :(得分:1)

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

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

E.g。结果完全一样。为了清楚起见,我个人更喜欢第一个,因为它类似于更准确的事情。

答案 4 :(得分: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();
}  

因此,在您的示例中,您可能会在finally块中获得NullReferenceException

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

using(OleDbConnection con = new OleDbConnection(connString))
{
    try
    {
        con.Open();
        return true;
    }catch(OleDbException ex)
    {
        //log error
        return false;
    }
}