tags:

views:

238

answers:

4

Hello,

I'm not against using "Using" statement, but I'm wondering how this affect performance when we use it inside one of another.

For example:

        using (test1 (type1))
        {
            using (test2(type2))
            {
                using (test2(type3))
                {
                }
            }
        }

This, will be translated in IL like this:

        try
        {
            try
            {
                try
                {
                }
                finally
                {
                }
            }
            finally
            {
            }
        }
        finally
        { 
        }

This will increase the size of assembly and, I believe, affect the performance of the application, right?

Shouldn't we use this?

        type1 test1 = new type1;
        type2 test2 = new type2;
        type3 test3 = new type3;

        try
        {

        }
        finally
        {
          test1.Dispose;
          test2.Dispose;
          test3.Dispose;
        }
+1  A: 

A try/catch/finally is not expensive unless an exception is thrown. And even then several people (Jon Skeet included) have said that a thrown exception is not that expensive.

In saying that, obviously you should not use exceptions for control flow.

Mitch Wheat
+21  A: 

No, don't use your second form. If test1.Dispose() throws an exception for some reason, test2.Dispose() and test3.Dispose() won't get called.

The performance difference, if any, will be microscopic. Don't throw away correctness for insignificant performance :)

Jon Skeet
Thanks, I didn't think on that ;).
Bruno Costa
>>Don't throw away correctness for insignificant performance.A thought for today!
Gary Willoughby
I totally agree see this article http://www.codinghorror.com/blog/archives/001218.html for another "microscopic optimization
WACM161
+5  A: 

I don't think worrying about the size of the assembly is something we typically need to worry about at the expense of writing more complicated to maintain code!

Your example code shows exactly why we need the compiler to generate the code it does. If your call to new type2() fails then the Dispose method on test1 would never be called, which would cause a resource leak.

Sean
+4  A: 

I think you're looking for the following:

using (test1(type1))
using (test2(type2))
using (test3(type3))
{
    // Code using test1/test2/test3 goes here.
}

It is equivalent to the first try-finally statement in your question, though clearly a lot more readable. Don't worry about the performance here really; it's good design practices and robust to use the nested method (as point out by previous posters), and additionally easily readable code (thanks to the multi-using statement) that count.

Noldorin
This one will still expand to three try/finally blocks - which is correct as pointed out in the accepted answer. The obvious benefit is readability.
Dan C.
Sorry, you're right. It does indeed expand to three try-finally blocks.
Noldorin