Sunday, September 11, 2005

PDC Precon: Leaky Anonymous Delegates



In a previous post of mine, I talked about how the AutoScroll functionality in the ScrollableControl class of Windows Forms has a leaky abstraction. Today, in Jeffrey Richter's precon, he talked about Anonymous Delegates which are essentially just C# syntactic sugar.

Instead of having to do this:
button1.Click += new EventHandler(button1_Click);

You can just write:
button1.Click += button1_Click;

Similarly, instead of instantiating a delegate to pass in to a method expecting a delegate, you can just do this:
ThreadPool.QueueUserWorkItem(SomeAsyncTask, 5);

Where SomeAsyncTask is method and 5 is a secondary parameter to QueueUserWorkItem.

They are basically shortcuts to help you write less code. That works great until you realize that you can also do this:

private void SetupButton4() {
// Syntactical Shortcut #4: No Need to Manually Wrap Local Variables
// in a Class to pass them to a Callback Method
Int32 numTimesBtn4Clicked = 0;
button4.Click +=
delegate
{
MessageBox.Show(String.Format("4th button clicked {0} times.",
++numTimesBtn4Clicked));
};
}

Notice how the code in the anonymous method accesses the local variable numTimesBtn4Clicked. What is happening is that there is an anonymous class defined and instantiated that has "numTimesBtn4Clicked" as an instance variable.

In other words, every time button4 is clicked, the message will update to reflect the number of times it was clicked. Additionally, every time you call SetupButton4() above, another EventHandler will be added to the Click event and it will have a new and separate copy of the numTimesBtn4Clicked variable.

If you understand the inner workings of what is going on, it makes sense but how many people who learn this "simplified" notation will be able to debug the problem when it doesn't work as expected?

0 Comments:

Post a Comment

<< Home