C# – Implicitly captured closures, ReSharper warning

cclosuresresharper

I normally know what "implicitly captured closure" means, however, today I came across the following situation:

public static void Foo (Bar bar, Action<int> a, Action<int> b, int c)
{
    bar.RegisterHandler(x => a(c)); // Implicitly captured closure: b
    bar.RegisterHandler(x => b(c)); // Implicitly captured closure: a
}

Why am I implicitly capturing the other action as well? If I comment either of the both lines, the other does not give me the warning. Anybody knows of what danger ReSharper is warning me?

Edit: ReSharper 8.0.1

Best Answer

The issue here is that when you close over a variable what happens behind the scenes is that the compiler creates a new unnamed type, gives that type an instance field for every variable that is closed over in that block, gives it a method for every anonymous method in that code block and then passes a single instance of that object around.

This means that the lifetime of the first delegate is keeping that closure object alive, and it has a reference to the object b, in addition to a, internally, and vice versa.

Now in your case, it's not an issue, as an Action isn't something that's particularly memory intensive, so keeping it alive for a bit longer isn't really a problem.

The C# team could, in theory, have ensured that in this particular case a new unnamed type could be created for each closure in the same block, but they chose not to as it makes the common case worse.