Using scope in C#

October 8, 2010

Microsoft managed code uses the garbage collector to reclaim space when objects go out of scope. This is a great advantage in that it frees the programmer from worrying about releasing resources. The programmer can’t predict when garbage collection will occur though. Unfortunately that also prevents you from using scope to your advantage. You can’t just put code in the destructor and assume it will be called when the object goes out of scope. If you created a mutex object (like I did in a previous post about C++ scoping) and left the unlock in the destructor you’d have no way to guarantee when your mutex would get unlocked.

There’s a handy trick to get around that problem. You can use scoping to your advantage if you combine the “using” keyword and the IDisposable interface. The IDisposable interface adds a Dispose() method to your class. The using keyword guarantees to call the Dispose method of any objects that are created using the keyword. The combination of the two of them does what the C++ scoping does.

Here’s an example of a class that is useful for winforms programmers. If you’re doing a rigorous job you know you should change the cursor to provide a visual indicatation the computer is working on a task. It’s a pain to ensure that the cursor is always set back to it’s original state when you finish the task. If an exception occurs you can end up with the user thinking the machine is still working on the task when it’s not.

public class BusyCursor : IDisposable
{
private Cursor _PreviousCursor;
private Form _ParentForm;

/// <summary>
/// Constructor
/// Saves form’s current cursor
/// Changes the cursor to a busy cursor
/// </summary>
/// <param name="ParentForm"></param>
public BusyCursor( Form ParentForm )
{
_ParentForm = ParentForm;
_PreviousCursor = _ParentForm.Cursor;
_ParentForm.Cursor = Cursors.WaitCursor;
}

#region IDisposable Members

public void Dispose()
{
_ParentForm.Cursor = _PreviousCursor;
}

#endregion
}

This class saves the cursor currently used by the form you pass to it. It then changes the cursor to the busy cursor. When it goes out of scope it restores the cursor to the original state.

You use the class like this:

public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void  button1_Click(object sender, EventArgs e)
{
using ( BusyCursor ShowBusyCursor = new BusyCursor(this) )
{
// long running process here
System.Threading.Thread.Sleep( 10000 );
}
}
}

It’s simple to implement, works very well, and isn’t terribly hard to understand.

Another day in the life of a workaday programmer batman.

++djs