Ambiguity in parameter type inference for C# lambda expressions : <p>My question is motivated by Eric Lippert's <a href="https://blogs.msdn.microsoft.com/ericlippert/2007/03/28/lambda-expressions-vs-anonymous-methods-part-five/">this blog post</a>. Consider the following code:</p>

<pre><code>using System;
class Program {
    class A {}
    class B {}
    static void M(A x, B y) { Console.WriteLine("M(A, B)"); }
    static void Call(Action&lt;A&gt; f) { f(new A()); }
    static void Call(Action&lt;B&gt; f) { f(new B()); }
    static void Main() { Call(x =&gt; Call(y =&gt; M(x, y))); }
}
</code></pre>

<p>This compiles successfully and prints <code>M(A, B)</code>, because the compiler figures out that the types of <code>x</code> and <code>y</code> in the lambda expressions should be <code>A</code> and <code>B</code> respectively. Now, add an overload for <code>Program.M</code>:</p>

<pre><code>using System;
class Program {
    class A {}
    class B {}
    static void M(A x, B y) { Console.WriteLine("M(A, B)"); }
    static void M(B x, A y) { Console.WriteLine("M(B, A)"); } // added line
    static void Call(Action&lt;A&gt; f) { f(new A()); }
    static void Call(Action&lt;B&gt; f) { f(new B()); }
    static void Main() { Call(x =&gt; Call(y =&gt; M(x, y))); }
}
</code></pre>

<p>This yields a compile-time error:</p>

<blockquote>
  <p>error CS0121: The call is ambiguous between the following methods or properties: 'Program.Call(Action&lt;Program.A&gt;)' and 'Program.Call(Action&lt;Program.B&gt;)'</p>
</blockquote>

<p>The compiler cannot infer the types of <code>x</code> and <code>y</code>. It may be that <code>x</code> is of type <code>A</code> and <code>y</code> is of type <code>B</code> or vice versa, and neither can be preferred because of full symmetry. So far so good. Now, add one more overload for <code>Program.M</code>:</p>

<pre><code>using System;
class Program {
    class A {}
    class B {}
    static void M(A x, B y) { Console.WriteLine("M(A, B)"); }
    static void M(B x, A y) { Console.WriteLine("M(B, A)"); }
    static void M(B x, B y) { Console.WriteLine("M(B, B)"); } // added line
    static void Call(Action&lt;A&gt; f) { f(new A()); }
    static void Call(Action&lt;B&gt; f) { f(new B()); }
    static void Main() { Call(x =&gt; Call(y =&gt; M(x, y))); }
}
</code></pre>

<p>This compiles successfully and prints <code>M(A, B)</code> again! I can guess the reason. The compiler resolves the overload of <code>Program.Call</code> trying to compile the lambda expression <code>x =&gt; Call(y =&gt; M(x, y))</code> for <code>x</code> of type <code>A</code> and for <code>x</code> of type <code>B</code>. The former succeeds, while the latter fails because of ambiguity detected when trying to infer the type of <code>y</code>. Therefore, the compiler concludes that <code>x</code> must be of type <code>A</code>.</p>

<p>Thus <em>adding more ambiguity results in less ambiguity</em>. This is weird. Moreover, this is inconsistent with what Eric wrote in the above-mentioned post:</p>

<blockquote>
  <p>If it has more than one solution then compilation fails with an ambiguity error.</p>
</blockquote>

<p>Is there any good reason for the current behavior? Is it just the matter of making the compiler's life easier? Or is it rather a flaw in the compiler/specification?</p>
