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

你。 提交于 2020-01-20 16:51:51

问题


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

try
{
    using()
    { 
      //Do stuff
    }
}
catch
{
    //Handle exception
}


using()
{
    try
    {
         //Do stuff
    }
    catch
    {
        //Handle exception
    }
}

回答1:


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



回答2:


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.




回答3:


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.




回答4:


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



回答5:


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



回答6:


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



来源:https://stackoverflow.com/questions/911626/catch-exceptions-within-a-using-block-vs-outside-the-using-block-which-is-bett

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!