Из сообщения об ошибке:
Аргументы типа для метода '[...].Map<T,T2>(System.Collections.Generic.List<T>, System.Func<T,T2>)
' не могут быть выведены из использования. Попробуйте указать аргументы типа явно.
Обратите внимание, что в сообщении об ошибке говорится, что оно не может определить аргументы типа. То есть он не может разрешить один из параметров типа T
или T2
. Это из-за §25.6.4 (Вывод аргументов типа) спецификации. Это часть спецификации, которая касается выводов параметров универсального типа.
Ничто не выводится из аргумента (но вывод типа завершается успешно), если выполняется любое из следующих условий:
[...]
Аргумент является группой методов.
Таким образом, компилятор не может использовать тип делегата Square
для вывода типа T2
. Обратите внимание, что если вы измените объявление на
public static List<T> Map<T>(List<T> inputs, Func<T, T> f) {
return inputs.ConvertAll((x) => f(x));
}
затем
var outputs = Map(inputs, Square);
законно. В этом случае уже решено, что T
является int
из-за того, что inputs
является List<int>
.
Теперь, более глубокий вопрос, почему выше спецификации? То есть, почему группы методов не играют роли в разрешении параметров типа? Я думаю, что это из-за таких случаев:
class Program {
public static T M<T>(Func<T, T> f) {
return default(T);
}
public static int F(int i) {
return i;
}
public static float F(float f) {
return f;
}
static void Main(string[] args) {
M(F); // which F am I?
}
}