Thursday, July 22, 2010

Cognitive Dissonance, or why I don't like this picture

This is legal code.  The Assert completes successfully:
class Program
{
    static EventHandler eh;
    static void Main(string[] args)
    {
        int i = 0;
        eh = (source, e) => { i = 1; };
        eh.Invoke(null, EventArgs.Empty);
        System.Diagnostics.Debug.Assert(i == 1);
    }
}

As you can see, it is possible for an event handler defined elsewhere to have an anonymous method assigned to it that modifies an internal variable in the method in which it is defined. (Ignore the fact that the above example has the event handler invoked synchronously and from within the same method that defines the anonymous method.  I’ve experimented and this still works even if these things aren’t true.)

I don’t like this. The whole idea of an internal variable is that it is internal: nothing outside the method in which it is defined can access it.

Yes, the anonymous method is defined within the method, but it can be invoked from outside the method.  It isn’t internal.

I’m sure there is a very sound reason why this was done. I just can’t think of any problem that opening a tunnel to a method’s internal variables solves that couldn’t be solved some other way.

1 Comments:

Blogger Steve said...

Old topic, but I recently ran into a (hard to diagnose) issue regarding this. Resharper now catches it and warns about it... it calls it "Access to modified closure".

I actually stumbled upon it reading C#'s threading book... http://www.albahari.com/threading
in the section titled "Lambda expressions and captured variables"
Here is some more info on it... http://stackoverflow.com/questions/235455/access-to-modified-closure
It's definitely an annoying one... (wishes for MSBuild warning)

12/14/2010 7:33 AM  

Post a Comment

<< Home