Possible Duplicate:
Why is Func<T> ambiguous with Func<IEnumerable<T>>?
I noticed a very weird overload resolution issue with generics...
Consider the following methods:
static void Foo<TSource>(TSource element, Func<TSource, int> selector)
{
"int".Dump();
}
static void Foo<TSource>(TSource element, Func<TSource, double> selector)
{
"double".Dump();
}
static T Identity<T>(T value)
{
return value;
}
(C# 4, tested in LINQPad)
If I try to call Foo
with a lambda expression as the selector, everything works fine:
Foo(42, x => x); // prints "int"
But if I replace x => x
with Identity
, the compiler can't decide between the 2 Foo
overloads:
Foo(42, Identity);
// The call is ambiguous between the following methods or properties:
// 'UserQuery.Foo<int>(int, System.Func<int,int>)' and
// 'UserQuery.Foo<int>(int, System.Func<int,double>)'
How can the second overload be a valid candidate ? Type inference correctly determines that TSource
is int
, so the T
parameter for the Identity
method has to be int
as well, so the return type has to be int
too... Identity
could be a Func<int,int>
or a Func<double,double>
, but not a Func<int,double>
!
And it gets worse! Even if I specify all type parameters explicitly, I still get the same error:
Foo<int>(42, Identity<int>); // The call is ambiguous...
How can there be any ambiguity here? As far as I can tell, there is no way the overload that takes a Func<int,double>
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.
Note that it does work if I explicitly create the delegate:
Foo(42, new Func<int, int>(Identity)); // prints "int"
So, could someone explain what's going on here? Also, why does it work with a lambda but not with a method group?