title: How do delegate/lambda typing and coercion work?
body: <p>I've noticed some examples of things that work and don't work when dealing with lambda functions and anonymous delegates in C#.  What's going on here?</p>
  
  <pre><code>class Test : Control {
      void testInvoke() {
          // The best overloaded method match for 'Invoke' has some invalid arguments
          Invoke(doSomething);
  
          // Cannot convert anonymous method to type 'System.Delegate' because it is not a delegate type
          Invoke(delegate { doSomething(); });
  
          // OK
          Invoke((Action)doSomething);
  
          // OK
          Invoke((Action)delegate { doSomething(); });
  
          // Cannot convert lambda expression to type 'System.Delegate' because it is not a delegate type
          Invoke(() =&gt; doSomething());
  
          // OK
          Invoke((Action)(() =&gt; doSomething()));
      }
  
      void testQueueUserWorkItem() {
          // The best overloaded method match for 'QueueUserWorkItem' has some invalid arguments
          ThreadPool.QueueUserWorkItem(doSomething);
  
          // OK
          ThreadPool.QueueUserWorkItem(delegate { doSomething(); });
  
          // The best overloaded method match for 'QueueUserWorkItem' has some invalid arguments
          ThreadPool.QueueUserWorkItem((Action)doSomething);
  
          // No overload for 'doSomething' matches delegate 'WaitCallback'
          ThreadPool.QueueUserWorkItem((WaitCallback)doSomething);
  
          // OK
          ThreadPool.QueueUserWorkItem((WaitCallback)delegate { doSomething(); });
  
          // Delegate 'WaitCallback' does not take '0' arguments
          ThreadPool.QueueUserWorkItem(() =&gt; doSomething());
  
          // OK
          ThreadPool.QueueUserWorkItem(state =&gt; doSomething());
      }
  
      void doSomething() {
          // ...
      }
  }
  </code></pre>
  
  <p>Well that's a lot of examples.  I guess my questions are the following:</p>
  
  <ol>
  <li><p>Why does <code>Invoke</code> always refuse a lambda function or an anonymous delegate, yet <code>ThreadPool.QueueUserWorkItem</code> does just fine?</p></li>
  <li><p>What the heck does "Cannot convert anonymous method to type 'System.Delegate' because it is not a delegate type" mean anyway?</p></li>
  <li><p>Why does <code>ThreadPool.QueueUserWorkItem</code> accept an anonymous delegate with no parameters, but not a lambda expression with no parameters?</p></li>
  </ol>