Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Catching exceptions thrown in the constructor of the target object of a Using block

using(SomeClass x = new SomeClass("c:/temp/test.txt"))
{
...
}

Inside the using block, all is fine with treating exceptions as normal. But what if the constructor of SomeClass can throw an exception?

like image 514
Mr. Boy Avatar asked Jul 29 '10 09:07

Mr. Boy


2 Answers

Put your using into the try catch f.e.

try
{
   using(SomeClass x = new SomeClass("c:/temp/test.txt"))
   {
       ...
   }
}
catch(Exception ex)
{
   ...
}
like image 86
Łukasz W. Avatar answered Sep 29 '22 16:09

Łukasz W.


Yes, this will be a problem when the constructor throws an exception. All you can do is wrap the using block within a try/catch block. Here's why you must do it that way.

using blocks are just syntactic sugar and compiler replaces each using block with equivalent try/finall block. The only issue is that the compiler does not wrap the constructor within the try block. Your code after compilation would have following conversion in the IL.

        //Declare object x of type SomeClass.
        SomeClass x;

        //Instantiate the object by calling the constructor.
        x = new SomeClass("c:/temp/test.txt");

        try
        {
            //Do some work on x.
        }
        finally
        {
            if(x != null)
                x.Dispose();
        }

As you can see from the code, the object x will not be instantiated in case when the constructor throws an exception and the control will not move further from the point of exception raise if not handled.

I have just posted a blog-post on my blog on this subject last night.

I'm just now wondering why C# designers did not wrap object construction within the try block which according to me should have been done.

EDIT

I think I found the answer why C# does not wrap object construction into try block generated in place of the using block.

The reason is simple. If you wrap both declaration and instantiation within the try block then the object would be out of scope for the proceeding finally block and the code will not compile at because, for finally block the object hardly exists. If you only wrap the construction in the try block and keep declaration before the try block, even in that case the it will not compile since it finds you're trying to use an assigned variable.

like image 34
this. __curious_geek Avatar answered Sep 29 '22 17:09

this. __curious_geek