この検査は、明らかに目に見えるよりも多くのクロージャ値がキャプチャされているという事実に注意を向けます。これは、これらの値の寿命に影響を与えます。
  
  次のコードを検討してください。
using System; 
public class Class1 {
    private Action _someAction;
    public void Method() {
        var obj1 = new object();
        var obj2 = new object();
        _someAction += () => {
            Console.WriteLine(obj1);
            Console.WriteLine(obj2);
        };
        // "Implicitly captured closure: obj2"
        _someAction += () => {
            Console.WriteLine(obj1);
        };
    }
}
  
  最初のクロージャーでは、obj1とobj2の両方が明示的にキャプチャされていることがわかります。コードを見るだけでこれを確認できます。2番目のクロージャでは、obj1が明示的にキャプチャされていることがわかりますが、ReSharperはobj2が暗黙的にキャプチャされていることを警告しています。
  
  これは、C#コンパイラの実装の詳細によるものです。コンパイル中に、クロージャーは、キャプチャーされた値を保持するフィールドと、クロージャー自体を表すメソッドを持つクラスに書き直されます。C#コンパイラは、メソッドごとにこのようなプライベートクラスを1つだけ作成します。メソッドで複数のクロージャが定義されている場合、このクラスには複数のメソッドが含まれます(各クロージャに1つ)。また、すべてのクロージャからキャプチャされたすべての値も含まれます。
  
  コンパイラが生成するコードを見ると、次のようになります(一部の名前は読みやすくするためにクリーンアップされています)。
public class Class1 {
    [CompilerGenerated]
    private sealed class <>c__DisplayClass1_0
    {
        public object obj1;
        public object obj2;
        internal void <Method>b__0()
        {
            Console.WriteLine(obj1);
            Console.WriteLine(obj2);
        }
        internal void <Method>b__1()
        {
            Console.WriteLine(obj1);
        }
    }
    private Action _someAction;
    public void Method()
    {
        // Create the display class - just one class for both closures
        var dc = new Class1.<>c__DisplayClass1_0();
        // Capture the closure values as fields on the display class
        dc.obj1 = new object();
        dc.obj2 = new object();
        // Add the display class methods as closure values
        _someAction += new Action(dc.<Method>b__0);
        _someAction += new Action(dc.<Method>b__1);
    }
}
  
  メソッドが実行されると、すべてのクロージャーについて、すべての値をキャプチャする表示クラスが作成されます。したがって、値がいずれかのクロージャで使用されていない場合でも、キャプチャされます。これは、ReSharperが強調している「暗黙の」キャプチャです。
  
  この検査の意味は、暗黙的にキャプチャされたクロージャ値は、クロージャ自体がガベージコレクションされるまでガベージコレクションされないということです。この値の有効期間は、値を明示的に使用しないクロージャーの有効期間に関連付けられています。クロージャの寿命が長い場合、特にキャプチャした値が非常に大きい場合は、コードに悪影響を与える可能性があります。
  
  これはコンパイラーの実装の詳細ですが、Microsoft(Roslynの前後)やMonoのコンパイラーなどのバージョンと実装全体で一貫しています。実装は、値型をキャプチャする複数のクロージャを正しく処理するために、説明どおりに機能する必要があります。たとえば、複数のクロージャがintをキャプチャする場合、それらは同じインスタンスをキャプチャする必要があります。これは、単一の共有プライベートネストクラスでのみ発生する可能性があります。これの副作用は、すべてのキャプチャされた値の有効期間が、任意の値をキャプチャするすべてのクロージャの最大有効期間になることです。