The Limber Lambda

Delegate Magic

Posted in Fun by Eric Smith on October 13, 2008

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.

Tagged with: , ,

Competition for Usenet?

Posted in Enrichment by Eric Smith on October 10, 2008

I wasn’t expecting much when I tried out the new developer Q & A forum Stack Overflow, but was pleasantly surprised when my question was answered in less than five minutes.  Not that I couldn’t have figured this out myself—there’s always a desperate rep glutton around willing to scoop up your questions … evidently.

Tab Position in VS2008

Posted in visual studio by Eric Smith on October 10, 2008

This bright young ladywoman makes it her duty to “tip” on VS on a daily basis without fail. For the most part, there isn’t anything hugely interesting, but occasionally there’s a gem.

In brief – don’t you hate it when your tabs don’t re-order so that the most recently accessed is also the first?  This has the effect that some file that you may be interested in “pops” off the right-hand side.  A small registry change ensures that tabs get re-ordered according to latest access; pretty handy–a small downside – tabs end up shifting around.

Tagged with:
Follow

Get every new post delivered to your Inbox.