Делегаты и F # «Значения функций первого класса» совершенно разные.
Делегаты - это механизм CLR, типобезопасной оболочки вокруг пар функция-указатель + объект (например, методы, указатель this
захватывается вместе с адресом метода).
Значения функции F #, с другой стороны, являются реализацией абстрактного класса FSharpFunc<,>
(раньше он назывался FastFunc<,>
до официального выпуска F #). Вызов происходит через обычные виртуальные методы, что намного быстрее, чем вызов делегата.
По этой причине команда F # не использовала делегатов.
Итак, если вы можете «реализовать» функции в качестве значений первого класса с помощью абстрактных классов / виртуальных методов, почему Microsoft добавила делегатов?
- Альтернативы не было В .NET 1.0 / 1.1 не было обобщений, поэтому вам приходилось определять новый тип делегата (= "тип функции") для каждой сигнатуры функции, которую вы хотите использовать.
- (Нет, просто использование интерфейсов, как в Java, не считается. :-P)
Хорошо, но у нас есть Generics начиная с .NET 2.0, почему у нас все еще есть делегаты? Почему мы не можем просто использовать Func<,>
и Action<>
для всего?
- Обратная совместимость
- Многоадресные делегаты Делегаты могут быть объединены в цепочки для формирования новых делегатов. Этот механизм используется для реализации событий в VB.NET и C #. За кулисами событие на самом деле представляет собой только одно делегатское поле. Используя синтаксис
+=
, вы по существу добавляете свой обработчик-делегат события в цепочку делегатов в поле события.
Помимо событий, есть ли причина использовать делегатов более FSharpFunc<,>
Да, один: каждая реализация FSharpFunc<,>
, которая включает в себя лямбда-выражения *, является новым классом. А в .NET классы закодированы в метаданных скомпилированной сборки. С другой стороны, делегаты не требуют дополнительных метаданных. Делегат типов делает, но создает эти типы делегатов свободны с точки зрения метаданных.
Но подождите, разве лямбда-выражения / анонимные методы C # не слишком реализованы как скрытые классы?
Да, C # лямбды берут худшее из обоих миров ^^