вторник, 6 ноября 2007 г.

Эрик Лептон обьясняет почему вывод типов...

не работает с функциями напрямую.
Вот тут - 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 в качестве параметра. Думаю любой это видит. Почему этого не должен видеть хотя бы в частном случае компилятор я не понимаю и вряд ли пойму.

Комментариев нет: