Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implicitly captured closures, ReSharper warning

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

like image 327
D.R. Avatar asked Sep 17 '13 20:09

D.R.


1 Answers

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.

like image 178
Servy Avatar answered Nov 13 '22 01:11

Servy