Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why *doesn't* ReSharper tell me “implicitly captured closure”?

This question and its answers explain the concept of implicitly captured closures very well. However, I occasionally see code that seems like it should generate the warning in question that in fact does not. For example:

public static void F()
{
  var rnd1 = new Random();
  var rnd2 = new Random();
  Action a1 = () => G(rnd1);
  Action a2 = () => G(rnd2);
}

private static void G(Random r)
{
}

My expectation was that I'd be warned that a1 implicitly captures rnd2, and a2 implicitly captures rnd1. However, I get no warning at all (the code in the linked question does generate it for me though). Is this a bug on ReSharper's part (v9.2), or does implicit capture not occur here for some reason?

like image 892
dlf Avatar asked Apr 13 '16 20:04

dlf


1 Answers

I think Resharper for some reason cannot spot implicitly captured variables in this case. You can verify yourself with some disassembler that compiler generates single class with both rnd1 and rnd2. With your example it's not crystal clear, but let's take this example from Eric Lippert blog post (https://blogs.msdn.microsoft.com/ericlippert/2007/06/06/fyi-c-and-vb-closures-are-per-scope/) where he describes an example of dangerous implicit capture:

Func<Cheap> M() {            
    var c = new Cheap();
    var e = new Expensive();
    Func<Expensive> shortlived = () => e;
    Func<Cheap> longlived = () => c;            
    shortlived();
    // use shortlived
    // use longlived
    return longlived;
}

class Cheap {

}

class Expensive {

}

Here it's clear that longlived delegate captures over Expensive variable and it won't be collected until it dies. But (at least for me), Resharper won't warn you about this. Cannot name it "bug" though, but there is certainly a place for an improvement.

like image 107
Evk Avatar answered Oct 18 '22 10:10

Evk