Я думаю, что я концептуально понимаю делегатов C #, но я изо всех сил пытаюсь найти пример из реальной жизни, где они были бы полезны. Можете ли вы дать некоторые ответы, подробно описывающие, как делегаты C # использовались в реальных приложениях и какие проблемы они позволили вам обойти.
16
Ответы:
Код GUI использует делегаты для обработки событий, таких как нажатие кнопок, перемещение окон. Использование делегата позволяет вам вызывать функцию всякий раз, когда происходит событие. Примером может служить связывание функции, которая сохраняет данные, с кнопкой «Сохранить» в интерфейсе. Когда кнопка нажата, она настроена на выполнение функции сохранения данных. Это полезно в программировании GUI, потому что вся ваша программа может ждать, пока пользователь что-то сделает, и у вас нет возможности узнать, что они будут делать в первую очередь. Использование делегатов позволяет подключать функциональные возможности вашей программы к пользовательскому интерфейсу таким образом, чтобы пользователь мог делать что-либо по своему усмотрению.
источник
Linq использует
Func<T>
иAction<T>
делегирует повсеместно в качестве параметров.Это позволяет вам использовать лямбда-выражения в качестве параметров и определять действие, которое необходимо выполнить как часть списка параметров.
источник
Практически все, что использует шаблон наблюдателя , вероятно, будет реализовывать делегатов.
Прочитайте описание, и вы, вероятно, представите несколько сценариев, в которых вы будете их использовать. Обработка событий в графическом интерфейсе - типичный пример.
источник
Делегаты чертовски полезны в асинхронном программировании.
У вас есть класс, который выполняет вещи асинхронно и имеет обратный вызов. Вы можете вызвать метод делегата после обратного вызова - и ваша реализация класса будет выполнять логику, описанную в вашем методе делегата.
источник
Делегаты особенно полезны в качестве решения для отверстия в средней схеме . По сути, во многих случаях вы хотите заключить уникальный набор инструкций в общий набор инструкций. Это особенно сложно, если инструкции до и после уникального бита должны совместно использовать состояние. С делегатами вы можете просто передать делегат в функцию. Функция выполняет бит before, выполняет делегат, затем выполняет бит after.
источник
В «старые времена» не-ООП-языков, таких как Fortran и C, было невероятно полезно иметь подпрограмму, получающую аргумент, который был указателем на функцию. Например,
qsort
функция работает с предоставленной пользователем функцией сравнения. Существует множество подпрограмм для решения обыкновенных дифференциальных уравнений или для оптимизации функций, и все они принимают указатели на функции в качестве аргументов.В оконных системах все виды обратных вызовов следуют одному и тому же шаблону.
В Лиспе, даже в первые дни, было нечто, называемое «функциональный аргумент» или FUNARG, который был не только функцией, но также содержал контекст хранения, где он мог помнить и взаимодействовать с частью внешнего мира.
Такая же потребность существует в языках ООП, за исключением того, что когда вы передаете адрес функции, вы также должны передавать адрес объекта, для которого функция является методом. Это две вещи, которые вы должны пройти. Таким образом, делегат - это только то, что позволяет использовать этот старый добрый шаблон.
источник
Вот простой пример, который показывает, насколько полезными могут быть делегаты при создании простого кода, который следует принципу DRY. Это также позволяет вам держать код очень близко к тому месту, где он необходим.
Вот реальный пример того преимущества, которое предоставляют делегаты.
источник
Моя первая встреча с делегатами заключалась в проверке обновления программы (Windows Form C # 3.5) путем загрузки файла с моего веб-сайта, но чтобы избежать проверки обновления, блокирующей всю программу, я использовал делегат и поток, чтобы сделать это асинхронно.
источник
Я видел интересные реализации шаблона стратегии, который эффективно использует делегатов. (т.е. стратегия является делегатом)
Тот, на который я смотрел, был для поиска пути, где алгоритм для поиска пути был делегатом, который мог быть (пере) назначен во время выполнения так, чтобы могли использоваться различные алгоритмы (BFS против A * и т. Д.)
источник
Многие классические шаблоны GoF могут быть реализованы с помощью делегатов: например, шаблон Command, шаблон Visitor, шаблон Strategy, шаблон Factory и шаблон Observer часто могут быть реализованы с помощью простого делегата. Иногда класс лучше (например, когда команде нужно имя или стратегический объект должен быть сериализован), но в большинстве случаев использование
Action<...>
илиFunc<...>
гораздо более элегантно, чем создание выделенного интерфейса с одним методом.источник