title: Delegate caching behavior changes in Roslyn
body: <p>Given the following code:</p>
  
  <pre><code>public class C
  {
      public void M()
      {
          var x = 5;
          Action&lt;int&gt; action = y =&gt; Console.WriteLine(y);
      }
  }
  </code></pre>
  
  <p>Using VS2013, .NET 4.5. When looking at the decompiled code, we can see that the compiler is caching the delegate <em>at the call site:</em></p>
  
  <pre><code>public class C
  {
      [CompilerGenerated]
      private static Action&lt;int&gt; CS$&lt;&gt;9__CachedAnonymousMethodDelegate1;
      public void M()
      {
          if (C.CS$&lt;&gt;9__CachedAnonymousMethodDelegate1 == null)
          {
              C.CS$&lt;&gt;9__CachedAnonymousMethodDelegate1 = new Action&lt;int&gt;(C.&lt;M&gt;b__0);
          }
          Action&lt;int&gt; arg_1D_0 = C.CS$&lt;&gt;9__CachedAnonymousMethodDelegate1;
      }
      [CompilerGenerated]
      private static void &lt;M&gt;b__0(int y)
      {
          Console.WriteLine(y);
      }
  }
  </code></pre>
  
  <p>Looking at the same code decompiled in Roslyn (using <a href="http://tryroslyn.azurewebsites.net/#K4Zwlgdg5gBAygTxAFwKYFsDcAoADsAIwBswBjGUogQxBBgGEYBvbGNmfYsmANwHswAExgBZABQBKGK3Yt283lQBOMAB4wAvDACsOBewCCpZGD4QAPJGQA+GFWOmImmAk236ZkHyKoAdAHUlMDQAGUhUMQQJPXYAX2xYoAAA">TryRoslyn</a>), yields the following output:</p>
  
  <pre><code>public class C
  {
      [CompilerGenerated]
      private sealed class &lt;&gt;c__DisplayClass0
      {
          public static readonly C.&lt;&gt;c__DisplayClass0 CS$&lt;&gt;9__inst;
          public static Action&lt;int&gt; CS$&lt;&gt;9__CachedAnonymousMethodDelegate2;
          static &lt;&gt;c__DisplayClass0()
          {
              // Note: this type is marked as 'beforefieldinit'.
              C.&lt;&gt;c__DisplayClass0.CS$&lt;&gt;9__inst = new C.&lt;&gt;c__DisplayClass0();
          }
          internal void &lt;M&gt;b__1(int y)
          {
              Console.WriteLine(y);
          }
      }
      public void M()
      {
          Action&lt;int&gt; arg_22_0;
          if (arg_22_0 = C.&lt;&gt;c__DisplayClass0.CS$&lt;&gt;9__CachedAnonymousMethodDelegate2 == null)
          {
              C.&lt;&gt;c__DisplayClass0.CS$&lt;&gt;9__CachedAnonymousMethodDelegate2 =
                              new Action&lt;int&gt;(C.&lt;&gt;c__DisplayClass0.CS$&lt;&gt;9__inst.&lt;M&gt;b__1);
          }
      }
  }
  </code></pre>
  
  <p>We can now see that the delegate is now lifted into a private class inside <code>C</code>, a similar behavior that we're used to seeing when closing over an instance variable / field (closure).</p>
  
  <p><em>I know</em> this is an implementation detail which may be subject to change at any given time. </p>
  
  <p>Still I wonder, what are the benefits of lifting the delegate into a new class and caching it there over simply caching it at the call site?</p>
  
  <p><strong>Edit:</strong></p>
  
  <p><a href="http://roslyn.codeplex.com/workitem/246">This issue</a> talks about the same behavior as asked here.</p>