【问题标题】:Using statement with try catch. What happens to instance from using statement?使用带有 try catch 的语句。 using 语句中的实例会发生什么?
【发布时间】:2012-09-03 10:21:22
【问题描述】:

如果我有一个围绕 try catch 语句的 using 块,如果 catch 引发异常,该 using 语句中的对象会发生什么情况?考虑以下代码:

using (IDatabaseConnectivityObject databaseConnectivityObject = new DbProviderFactoryConnectionBasicResponse())
{
    try
    {
        Foo();
    }
    catch (ArgumentNullException e)
    {
        throw;
    }
}

如果我们假设 Foo() 失败并且异常被触发并有效地中断了程序,那么 databaseConnectivityObject 会被释放吗?这很重要的原因是该对象具有与之关联的数据库连接。

【问题讨论】:

    标签: c# .net using-statement


    【解决方案1】:

    您可以将using 视为try-finally 的简写。因此您的代码相当于:

    IDatabaseConnectivityObject databaseConnectivityObject = new DbProviderFactoryConnectionBasicResponse();
    try
    {
        try
        {
            Foo();
        }
        catch(ArgumentNullException e)
        {
            throw;
        }
    }
    finally
    {
      if(databaseConnectivityObject != null)//this test is often optimised away
        databaseConnectivityObject.Dispose()
    }
    

    这样看,你可以看到Dispose()如果抛出异常,确实会被调用,因为try-finally在try-catch之外。

    这正是我们使用using的原因。

    【讨论】:

      【解决方案2】:

      我们假设 Foo() 失败并且异常被触发并且有效 中断程序会不会处理databaseConnectivityObject?

      会的。内部使用使用try-finally(使用仅适用于实现IDisposable的那些)

      来自MSDN- using statement

      using 语句确保 Dispose 被调用 即使 当您在对象上调用方法时发生异常。你可以 通过将对象放在 try 块中来实现相同的结果,然后 然后在 finally 块中调用 Dispose;事实上,这就是 using 语句由编译器翻译。

      【讨论】:

      • 所以实际上 using 是说尝试 using 块中的所有代码,最后在我们看不到的 finally 块中调用 MyObject.Dispose()?
      • @CSharpened,绝对正确,就是这样。您可以在答案中的链接上看到更详细的示例
      【解决方案3】:

      是的,您的 using 块将处理 databaseConnectivityObject,无论您是否有 try - catch 块。

      您说得对,using 块很重要,您应该将它用于所有实现 IDisposable 的类,以确保即使在发生异常时也能正确处理它们。

      来自MSDN- using statement

      using 语句确保 Dispose 被调用 即使 当您在对象上调用方法时发生异常。你可以 通过将对象放入 try 块中来获得相同的结果,然后 然后在 finally 块中调用 Dispose;事实上,这就是 using 语句由编译器翻译。

      【讨论】:

        【解决方案4】:

        在实现using 块时,如果它实现了IDisposable 接口,括号中的对象将被释放。

        即使foo() 失败,它仍然会被释放。

        using语句中的对象必须实现IDisposable接口。

        此外,"Uses of using in c sharp""using statement vs try finally" 这些问题进一步说明了using 语句的用途和实用性。

        C# Language Specification 的第 8.13 节清楚地详细说明了 using 语句。

        【讨论】:

          【解决方案5】:

          您的using 代码相当于

          IDatabaseConnectivityObject databaseConnectivityObject = new IDatabaseConnectivityObject ();
          try
          {
          //To do code here
          }
          finally
          {
              if(databaseConnectivityObject!=null)
              {
                 databaseConnectivityObject.Dispose();
              }
          }
          

          一个using语句主要分为三部分,即

          1. 收购
          2. 用法
          3. 处置

          首先,通过finally语句获取资源并在try块上进行使用。最后,对象被放置在finally块中,如上面的等效代码中给出的......

          【讨论】:

          • 我认为值得指出的是,在解释它时,空测试通常会在可能的情况下被优化掉。有人可能会尝试自己尝试最终作为微优化。无论如何这都是一个坏主意(降低易读性是不值得的),但事实上它甚至不会提供他们认为可能的微小好处,这将进一步阻碍它。
          猜你喜欢
          • 2011-09-17
          • 2014-06-18
          • 2014-03-10
          • 2011-01-06
          • 1970-01-01
          • 2022-01-13
          • 2012-11-20
          • 1970-01-01
          • 2014-09-30
          相关资源
          最近更新 更多