Спецификация языка C # описывает вывод типов в Разделе §7.5.2. Там - это деталь, которую я не понимаю. Рассмотрим следующий случай:
// declaration
void Method<T>(T obj, Func<string, T> func);
// call
Method("obj", s => (object) s);
Оба компилятора Microsoft и Mono C # правильно выводят T
= объект
, но мое понимание алгоритм в спецификации выдаст T
= строку
, а затем завершится ошибкой.Вот как я это понимаю:
Первая фаза
Если Ei - анонимная функция, явный вывод типа параметра (§7.5.2.7) выполняется из Ei в Ti
⇒ не имеет никакого эффекта, потому что лямбда-выражение не имеет явных типов параметров. Правильно?
В противном случае, если Ei имеет тип U и xi является параметром значения, тогда вывод нижней границы выполняется от U к Ti.
⇒ первый параметр имеет статический тип строка
, поэтому он добавляет строку
к нижним границам для T
, верно?
Вторая фаза
Все нефиксированные переменные типа Xi, которые не зависят от (§7.5.2.5) любого Xj, являются фиксированными (§7.5.2.10).
⇒ T
не исправлен; T
ни от чего не зависит ... так что T
нужно исправить, верно?
§7.5.2.11 Исправление
Набор типов кандидатов Uj начинается как множество всех типов в множестве границ для Xi.
⇒ { строка
(нижняя граница)}
Затем мы исследуем каждую границу для Xi по очереди: [...] Для каждой нижней границы U элемента Xi все типы Uj, для которых нет неявное преобразование из U удаляются из набора кандидатов. [...]
⇒ ничего не удаляет из набора кандидатов, верно?
Если среди оставшихся типов кандидатов Uj есть уникальный тип V, из которого происходит неявное преобразование во все другие типы кандидатов , то Xi фиксируется на V.
⇒ Поскольку существует только один тип кандидата, это пусто, поэтому Xi фиксируется на строке
.Верно?
Так в чем я ошибаюсь?