Другие уже указывали, что существует бесконечно много возможных типов делегатов, которые вы могли бы иметь в виду;Что такого особенного в Func
, что оно заслуживает того, чтобы быть значением по умолчанию вместо Predicate
или Action
или любой другой возможности?И, что касается лямбд, почему очевидно, что цель состоит в том, чтобы выбрать форму делегата, а не форму дерева выражений?
Но мы могли бы сказать, что Func
является особенным, и что предполагаемый типЛямбда или анонимный метод - это функция чего-то.У нас все еще были бы все виды проблем.Какие типы вы хотели бы получить в следующих случаях?
var x1 = (ref int y)=>123;
Не существует типа Func<T>
, который принимает ref что-либо.
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.