День двести сорок пятый. #BestPractices

Разработка для Расширяемости

События и Функции обратного вызова

Функции обратного вызова - это точки расширения, которые позволяют платформе вызывать пользовательский код через делегата. Эти делегаты обычно передаются в структуру через параметр метода.

События - это особый случай обратных вызовов, который поддерживает удобный и согласованный синтаксис для предоставления делегата (обработчик события). Кроме того, разработчики помогают в этом, предоставляя API на основе событий.

⚠️ РАССМОТРИТЕ использование обратных вызовов, чтобы позволить пользователям выполнять свой код на определённых этапах работы фреймворка.

⚠️ РАССМОТРИТЕ использование событий, чтобы позволить пользователям настраивать поведение фреймворка без необходимости понимания объектно-ориентированного проектирования.

ИСПОЛЬЗУЙТЕ события вместо обратных вызовов, где это возможно, потому что они знакомы более широкому кругу разработчиков.

ИЗБЕГАЙТЕ использования обратных вызовов в чувствительных к производительности API.

ИСПОЛЬЗУЙТЕ типы Func<…>, Action<…> или Expression<…> вместо пользовательских типов делегатов при определении API с обратными вызовами. Func<…> и Action<…> представляют обобщённые делегаты. Expression<…> представляет определения функций, которые могут быть скомпилированы и впоследствии вызваны во время выполнения, но также могут быть сериализованы и переданы удаленным процессам.

ИСПОЛЬЗУЙТЕ замеры производительности, чтобы понимать последствия использования Expression<…> вместо делегатов Func<…> и Action<…>. Типы Expression<…> в большинстве случаев логически эквивалентны делегатам Func<…> и Action<…>. Основное различие между ними заключается в том, что делегаты предназначены для использования в сценариях локальных процессов, а выражения предназначены для случаев, когда необходимо произвести оценку выражения в удаленном процессе или машине.

❗️ ЗАМЕТЬТЕ, что, вызывая делегата, вы выполняете произвольный код, что может иметь последствия для безопасности, корректности и совместимости.



Источник: https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/