Note that there are some explanatory texts on larger screens.

plurals
  1. POGenerics, overload resolution and delegates (sorry, can't find a better title)
    primarykey
    data
    text
    <blockquote> <p><strong>Possible Duplicate:</strong><br> <a href="https://stackoverflow.com/questions/4573011/why-is-funct-ambiguous-with-funcienumerablet">Why is Func&lt;T&gt; ambiguous with Func&lt;IEnumerable&lt;T&gt;&gt;?</a> </p> </blockquote> <p>I noticed a very weird overload resolution issue with generics...</p> <p>Consider the following methods:</p> <pre><code>static void Foo&lt;TSource&gt;(TSource element, Func&lt;TSource, int&gt; selector) { "int".Dump(); } static void Foo&lt;TSource&gt;(TSource element, Func&lt;TSource, double&gt; selector) { "double".Dump(); } static T Identity&lt;T&gt;(T value) { return value; } </code></pre> <p>(C# 4, tested in LINQPad)</p> <p>If I try to call <code>Foo</code> with a lambda expression as the selector, everything works fine:</p> <pre><code>Foo(42, x =&gt; x); // prints "int" </code></pre> <p>But if I replace <code>x =&gt; x</code> with <code>Identity</code>, the compiler can't decide between the 2 <code>Foo</code> overloads:</p> <pre><code>Foo(42, Identity); // The call is ambiguous between the following methods or properties: // 'UserQuery.Foo&lt;int&gt;(int, System.Func&lt;int,int&gt;)' and // 'UserQuery.Foo&lt;int&gt;(int, System.Func&lt;int,double&gt;)' </code></pre> <p>How can the second overload be a valid candidate ? Type inference correctly determines that <code>TSource</code> is <code>int</code>, so the <code>T</code> parameter for the <code>Identity</code> method has to be <code>int</code> as well, so the return type has to be <code>int</code> too... <code>Identity</code> could be a <code>Func&lt;int,int&gt;</code> or a <code>Func&lt;double,double&gt;</code>, but not a <code>Func&lt;int,double&gt;</code>!</p> <p>And it gets worse! Even if I specify all type parameters explicitly, I still get the same error:</p> <pre><code>Foo&lt;int&gt;(42, Identity&lt;int&gt;); // The call is ambiguous... </code></pre> <p>How can there be any ambiguity here? As far as I can tell, there is no way the overload that takes a <code>Func&lt;int,double&gt;</code> can be a candidate. I guess the explanation must be somewhere in the specifications, but I can't find the relevant bit... or it might be a bug in the compiler, but I guess it's unlikely.</p> <p>Note that it does work if I explicitly create the delegate:</p> <pre><code>Foo(42, new Func&lt;int, int&gt;(Identity)); // prints "int" </code></pre> <p>So, could someone explain what's going on here? Also, why does it work with a lambda but not with a method group?</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload