Reputation: 12102
Why does the following correctly infer the type of T:
void foo<T>(IEnumerable<T> src){
src.Select(id => id);
}
But this doesn't:
Func<T, T> Id<T>() {
return (T t) => t;
}
void foo() {
new List<int>().Select(Id());
}
Upvotes: 2
Views: 574
Reputation: 9496
Section 7.4.2 Type Inference
If the supplied number of arguments is different than the number of parameters in the method, then inference immediately fails. Otherwise, assume that the generic method has the following signature:
Tr M(T1 x1 … Tm xm)
With a method call of the form M(E1 …Em) the task of type inference is to find unique type arguments S1…Sn for each of the type parameters X1…Xn so that the call M(E1…Em)becomes valid.
This code should work fine:
Func<T, T> Id<T>()
{
return (T t) => t;
}
void foo()
{
new List<int>().Select(Id<int>());
}
Upvotes: 1
Reputation: 1502985
Type argument inference always works on method arguments - including the first argument to an extension method like Select
.
So your second call is effectively:
Enumerable.Select(new List<int>(), Id())
Select
will be able to use those arguments to infer the type argument there, but the Id()
call doesn't have any arguments, and type inference doesn't try to work out what the type argument should be based on how the method is used.
In other words, it's not Select
that's the problem here - it's Id()
. So this would work:
// No type inference available
var idFunc = Id<int>();
// Type argument to Select is inferred
var selection = new List<int>.Select(idFunc);
Upvotes: 8