Вот тут - C# 3.0 Return Type Inference Does Not Work On Member Groups
Обьяснение туманное и запутанное. Интересен тот факт что в первоначальной спецификации на версию 3.0 это было заявлено.
О чем речь собственно...
Пусть есть вот такой код:
public static IEnumerable<R> transformation<C, R>(this IEnumerable<C> collection, Func<C, R> projection)
{
foreach (C c in collection)
yield return projection(c);
}
public static int to_42(int value)
{
return 42;
}
Мы хотим применить to_42 к transformation. Тогда если где-то ниже мы напишем:
int[] numbers = new int[] { 1, 2, 3, 4, 5 };
foreach (int i in numbers.transformation(collections.to_42))
{
Console.WriteLine(i);
}
Мы получим ошибку компиляции. Вот такую:
error CS0411: The type arguments for method 'alogrithm.collections.transformation<C,R>(System.Collections.Generic.IEnumerable<C>, System.Func<C,R>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
Варианты при которых сообщения об ошибки не получаются:
Func<int, int> _f = collections.to_42;
foreach (int i in numbers.transformation(_f))
...
foreach (int i in numbers.transformation(new Func<int, int>(collections.to_42)))
...
foreach (int i in numbers.transformation((x) => { return collections.to_42(x); }))
...
foreach (int i in numbers.transformation<int,int>(collections.to_42))
...
Все сводится к тому что мы так или иначе задали тип (в основном возвращаемого значения) явно. Т.е. компилятор самостоятельно понять какой именно тип возвращаемого значения у функции to_42 не может. И Эрик подробно и обстоятельно обьясняет почему это абсолютно правильно.
Скажу честно - я ничего не понял из этих объяснений.
Я вижу какими типами должна быть инстанцииирована ( в терминах шаблонов С++ ) transformation при использовании to_42 в качестве параметра. Думаю любой это видит. Почему этого не должен видеть хотя бы в частном случае компилятор я не понимаю и вряд ли пойму.
Комментариев нет:
Отправить комментарий