Catch exceptions within a using block vs outside the using block - which is better?

后端 未结 6 1745
甜味超标
甜味超标 2020-12-25 12:29

Is there any difference between these tow pieces of code & which approach is better.

try
{
    using()
    { 
      //Do stuff
    }
}
catch
{
    //Hand         


        
相关标签:
6条回答
  • 2020-12-25 12:57

    Ultimately, you could combine both methods to overcome both drawbacks:

    IFoo f;
    try{
      f = new Foo();
      f.Bar();
    catch{
      // Do something exceptional with f
    } finally{
      if(f != null) f.Dispose();
    }
    
    0 讨论(0)
  • 2020-12-25 13:04

    I presume you mean:

    using (var x = new Y(params))
    {
    }
    

    In both cases? Then the obvious difference is the scope of x. In the second case, you could access x in the catch clause. In the first case, you could not.

    I'll also take the opportunity to remind you not to "handle" an exception unless you can really do something about it. That includes logging the exception, which would be ok, unless the environment you're operating in does the logging for you (as ASP.NET 2.0 does by default).

    0 讨论(0)
  • 2020-12-25 13:06

    As mentioned above, only the first method will catch exceptions in the IDisposable object's initialization, and will have the object in-scope for the catch block.

    In addition, the order of operations for the catch and finally blocks will be flipped depending on their nesting. Take the following example:

    public class MyDisposable : IDisposable
    {
        public void Dispose()
        {
            Console.WriteLine("In Dispose");
        }
    
        public static void MethodOne()
        {
            Console.WriteLine("Method One");
            using (MyDisposable disposable = new MyDisposable())
            {
                try
                {
                    throw new Exception();
                }
                catch (Exception ex)
                {
                    Console.WriteLine("In catch");
                }
            }
        }
    
        public static void MethodTwo()
        {
            Console.WriteLine("Method Two");
            try
            {
                using (MyDisposable disposable = new MyDisposable())
                {
                    throw new Exception();
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("In catch");
            }
        }
    
        public static void Main()
        {
            MethodOne();
            MethodTwo();
        }
    }
    

    This will print:

    Method One
    In catch
    In Dispose
    Method Two
    In Dispose
    In catch
    
    0 讨论(0)
  • 2020-12-25 13:08

    Yes. In the first, the resource you are "using" will be disposed before the catch block is executed. In the later, it will be disposed afterwards. Moreover, the "foo" statement isn't under the scope of the catch clause. A "using" block is almost syntactic sugar such that

    using (foo)
    {
    }
    

    is

    try
    {
      foo;
    }
    finally
    {
      foo.Dispose();
    }
    

    Which behaviour is "better" is not obvious without context.

    0 讨论(0)
  • 2020-12-25 13:13

    There's a difference between these blocks. In the second case the exception won't be caught if it is thrown in the using() line (for example instantiating an IDisposable object and the constructor throws an exception). Which one is better will depend on your specific needs.

    0 讨论(0)
  • 2020-12-25 13:17

    There are differences, but it namely boils down to the fact that a using block creates it own try and scope blocks.

    try
    {
        using(IDisposable A = GetDisposable())
        { 
          //Do stuff
        }
    }
    catch
    {
        //Handle exception
        // You do NOT have access to A
    }
    
    
    using(IDisposable A = GetDisposable())  //exception here is uncaught
    {
        try
        {
             //Do stuff
        }
        catch
        {
            //Handle exception
            // You DO have access to A
        }
    }
    
    0 讨论(0)
提交回复
热议问题