C# · CodeProject · Dotnet

Proving Using block is Try, finally in IL

Hi Reader,

Let me remind you at first that this article will not solve any of your real world problem. Rather this is one of my crazy brain thinking article i usually do like i did on properties article. I am sure this is not a great article nor i am boasting about my thinking. I am also sure you will be having much better idea than this, if you do kindly comment for my learning’s 🙂

Ok Enough, lets start..

Now in .NET (C# here) most of us know that Using() block is used for safe cleanup operations on a chunk of code. And we also know that, Using() block only works on members which explicitly implement IDisposable interface

If your an experienced programmer, you’ll also know (theoretically or by IL verification) internally (IL) Using() block is represented as just a Try and a Finally blocks. Where in, the compiler writes a Dispose() method call on the object which Using() is enclosed.

For the following code :

using(var value = new List<string>().GetEnumerator()) { }

Equivalent IL code:

.try
{
IL_000c: nop
IL_000d: nop
IL_000e: leave.s IL_001f
} // end .try
finally
{
IL_0010: ldloca.s enumr
IL_0012: constrained. valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator<string>
IL_0018: callvirt instance void [mscorlib]System.IDisposable::Dispose()
IL_001d: nop
IL_001e: endfinally
} // end handler

As you can see from above IL code, the Using() block is being converted to Try and Finally and inside Finally block, an explicit call to Dispose() method is called. Thus operation via Using() block is much safer in cleaning up/freeing up resources much as the same way if a developer had explicitly wrote a Try and Finally blocks and do write some manual clean up code under Finally block.

So by now we know what Finally is for, and we also know that Finally block will be called by runtime before completely returning back from that scope. As a matter of fact, we also know that compiler won’t allow Finally block with out a Try block.

Let me say my intention for this article again.

  • What if there was no IL Disassembler tools avail.
  • What if none of us knew how to read IL code
  • What if Microsoft kept IL structure knowledge off from public due to ballmer’s crazyness perhaps 😛 lol
  • On of us just don’t want to accept what theoretical point in MSDN or by some book authors mention.

So in all the above cases, its better to validate ourselves that Using() block really is what these MSDN/Book authors/Few Experts says.

So this evening i was questioning myself as to how i can prove to myself that Using() block is just Try-Finally block inside. So as i was thinking, i just got this very simple small idea.

Since i knew that before returning from Using, Dispose() on its member is called. So i created a class as shown:

class MyClass : IDisposable
{
public void Dispose()
{
Console.WriteLine(“Dispose called”);
}
}

Then in the main function, i altered the using block as shown:

 static void Main(string[] args)
{
using (MyClass myObj = new MyClass())
{
return;
}
Console.WriteLine(“Completed..”); //Code Unreachable
}

Now as per the above Using() block, the return statement makes the CLR return control immediately from the Main method, with out proceeding further. So when you execute the above code, as soon as CLR encounters return statement, the Dispose() method in the custom class will be called before actually returning from it.

Thanks 🙂

Hence the theoretical point about Using() internals is proved.

P.S: Your valuable comments are appreciated 🙂

Advertisements

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s