The Limber Lambda

Eric Smith’s technical musings

Delegate Magic

with one comment

So, you’ve used delegates with gay abandon and everything just seems to work.  In particular, this sort of thing works without a hitch:

	class Proggy
	{
		public static void Main(string[] args)
		{
			var p = new Proggy();
			Console.WriteLine(p.StuffThatNeedsDoing()());
			Console.ReadLine();
		}

		public Func<int> StuffThatNeedsDoing()
		{
			var ia = new int[1];
			ia[0] = 2;
			return (() => ia[0] * ia[0]);
		}
	}

I’m referring, of course, to the bit that returns a delegate that references a method variable. I’ve always been curious as to how that works, so I dug into the IL to reveal the magic.

The interesting bit is the implementation of StuffThatNeedsDoing():

Let’s take a closer look as to what is happening here:

  • Behind the scenes, the compiler generates a nested class called <>c__DisplayClass1
    and encapsulates our int[] in it.
  • L_0000 to L_000e news up an instance of <>c__DisplayClass1 and assigns the ia field therein to a new int[] of size 1.
  • L_0013 to L_001b assigns the value 2 to element 0 of ia within the instance.
  • L_001c to L_0028 news up a Func<int>, passing to the constructor the reference to <>c__DisplayClass1 and the address of a method on <>c__DisplayClass1 called <StuffThatNeedsDoing>b__0 (which turns out to be our delegate implementation).
  • The new Func<int> is then effectively returned.

In short – it looks (unsurprisingly) like the local ia is no longer a local, and naively referencing it from within the delegate has caused it to be treated like a heap variable.  Of course our “local” ia now has a lifetime consistent with the lifetime of the delegate returned by StuffThatNeedsDoing—not a problem if we don’t mind, but what if we had referenced a “local” IDataReader from within our delegate?  The IDataReader, and associated unmanaged resources, would lurk around possibly for a very long time … something to be aware of.

So, as it turns out, the thing that binds a function to it’s “environment” (in this case, the local that we referenced) is known as a closure.

Advertisement

Written by Eric Smith

October 13, 2008 at 5:48 AM

Posted in Fun

Tagged with , ,

One Response

Subscribe to comments with RSS.

  1. skepticabin

    October 27, 2008 at 6:45 AM


Leave a Reply

Fill in your details below or click an icon to log in:

Gravatar
WordPress.com Logo

You are commenting using your WordPress.com account. 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 )

Connecting to %s

Follow

Get every new post delivered to your Inbox.