Suppose I have
public static List<T2> Map<T,T2>(List<T> inputs, Func<T, T2> f)
{
return inputs.ConvertAll((x) => f(x));
}
private int Square(int x) { return x*x; }
public void Run()
{
var inputs = new List<Int32>(new int[]{2,4,8,16,32,64,128,256,512,1024,2048});
// this does not compile
var outputs = Map(inputs, Square);
// this is fine
var outputs2 = Map<Int32,Int32>(inputs, Square);
// this is also fine (thanks, Jason)
var outputs2 = Map<Int32,Int32>(inputs, (x)=>x*x);
// also fine
var outputs2 = Map(inputs, (x)=>x*x);
}
Why does it not compile?
EDIT: The error is:
error CS0411: The type arguments for method ‘Namespace.Map<T,T2>(System.Collections.Generic.List<T>, System.Func<T,T2>)’ cannot be inferred from the usage. Try specifying the type arguments explicitly.
Why do I have to specify the type of the Map() function? Can it not infer this from the passed Func<T> ? (in my case, Square)
Is the answer the same as for
C# 3.0 generic type inference – passing a delegate as a function parameter ?
From your error message:
Note that the error message says that it can not figure out the type arguments. That is, it is having trouble resolving one of the type parameters
TorT2. This is because of §25.6.4 (Inference of type arguments) of the specification. This is the part of the specification the deals with inferring generic type parameters.Thus, the compiler is not able to use the delegate type of
Squareto infer the type ofT2. Note that if you change the declaration tothen
is legal. In this case, it has already resolved that
Tisintfrom the fact thatinputsis aList<int>.Now, the deeper question is why is the above the specification? That is, why don’t method groups play a role in type parameter resolution? I think it’s because of cases like this: