Другие уже указывали, что существует бесконечно много возможных типов делегатов, которые вы могли иметь в виду; Что такого особенного в том, Func
что оно заслуживает того, чтобы быть по умолчанию вместо Predicate
или Action
или любой другой возможности? А для лямбда-выражений, почему очевидно, что намерение состоит в том, чтобы выбрать форму делегата, а не форму дерева выражения?
Но мы могли бы сказать, что Func
это особенное, и что предполагаемый тип лямбда или анонимного метода - это Func чего-то. У нас по-прежнему будут всевозможные проблемы. Какие типы вы хотели бы вывести в следующих случаях?
var x1 = (ref int y)=>123;
Нет такого Func<T>
типа, который мог бы что-либо использовать.
var x2 = y=>123;
Мы не знаем тип формального параметра, но знаем возвращаемый результат. (Или мы? Возвращаемый int? Длинный? Короткий? Байт?)
var x3 = (int y)=>null;
Мы не знаем возвращаемого типа, но он не может быть недействительным. Тип возврата может быть любым ссылочным типом или любым типом значения, допускающим значение NULL.
var x4 = (int y)=>{ throw new Exception(); }
Опять же, мы не знаем возвращаемый тип, и на этот раз он может быть недействительным.
var x5 = (int y)=> q += y;
Предполагается, что это будет лямбда-выражение, возвращающее пустое значение, или что-то, что возвращает значение, присвоенное q? Оба законны; что выбрать?
Вы можете сказать, что просто не поддерживайте ни одну из этих функций. Просто поддержите «нормальные» случаи, когда типы могут быть определены. Это не помогает. Как это облегчит мою жизнь? Если функция иногда работает, а иногда дает сбой, мне все равно придется написать код, чтобы обнаруживать все эти ситуации сбоя и выдавать для каждой значимое сообщение об ошибке . Нам все еще нужно указать все это поведение, задокументировать его, написать для него тесты и так далее. Это очень дорогая функция которая избавляет пользователя от полдюжины нажатий клавиш. У нас есть лучшие способы повысить ценность языка, чем тратить много времени на написание тестовых примеров для функции, которая не работает половину времени и не дает никаких преимуществ в тех случаях, когда она действительно работает.
Ситуация, в которой это действительно полезно:
var xAnon = (int y)=>new { Y = y };
потому что для этого не существует "говорящего" типа. Но у нас эта проблема возникает постоянно, и мы просто используем вывод типа метода, чтобы определить тип:
Func<A, R> WorkItOut<A, R>(Func<A, R> f) { return f; }
...
var xAnon = WorkItOut((int y)=>new { Y = y });
и теперь вывод типа метода определяет, что это за тип функции.
Func<>
принять до 16 аргументов.