Рекомендации: когда следует использовать делегат в .NET?

Возможные дубликаты:
Использование делегатов: бизнес-приложения
Где использовать делегатов?

Привет,

Я новичок в концепции делегата в .NET. Я еще не использовал их и думаю, что они, вероятно, существуют по уважительной причине - когда я должен использовать делегат?

Примеры очень приветствуются.

Ответ 1

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

List<Foo> foos = new List<Foo>();
foos.Find(delegate(Foo foo)
    {
        if(foo.CustomProperty.Contains("special value"))
        {
            return false;
        }
        return true;
    });

Вышеприведенный пример является абсолютно произвольным, но указывает, что вы можете отделить то, что (итерация и выполнение критериев "найти" ) из того, как (как определить, что-то найдено).

Ответ 2

Делегаты предоставляют вам способ передать поведение в качестве параметра.

Обычными примерами являются события и асинхронное программирование, в которых для вызова в ваш объект отвечает нечто иное, кроме вашего объекта. Вы предоставляете это событие делегату, и теперь оно может запускать поведение, связанное с этим делегатом.

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

В ответ на комментарий:

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

Ответ 4

События используют делегатов за кулисами.

Если вы используете события, вы использовали делегатов, но только с более сильным синтаксисом.

В основном для них используется для обратных вызовов или программирования на основе событий.

Ответ 5

Делегаты используются для программирования, управляемого событиями. Наилучшие практики часто касаются развязывания кода (или "свободной" связи). Используя делегаты, вы можете подписывать методы на события, вместо того, чтобы иметь X-вызов Y, если что-то происходит, а затем Y вызывает Z при определенном условии и т.д.

Ответ 6

События и обратные вызовы в руководствах .NET объясняют это хорошо.

В целом вы должны предпочесть события в простых API-интерфейсах, потому что есть сильная поддержка IDE, и большинство разработчиков довольны событиями. Однако, если вам нужно, чтобы пользователь предоставил код, который будет выполнен, вам следует рассмотреть возможность использования делегатов или виртуальных участников. Обратные вызовы менее эффективны, но если вы используете делегатов типа Action и Func, вы разрешаете lambdas.

Ответ 7

Пример: один ресурс используется несколькими объектами. Ресурс нуждается в асинхронном обратном вызове для этих объектов, но природа ресурса требует, чтобы только один запрос был активным в данный момент времени, и этот запрос привязан к определенному объекту. Из-за архитектуры я не хочу передавать объекты в ресурс, поэтому вместо этого я отправляю ресурс делегатом из каждого объекта и сохраняю эти делегаты вместе с идентификаторами объектов. Когда запрос сделан, я могу найти соответствующий идентификатор объекта и вызвать его конкретный делегат.

Первоначально я реализовал это с событием, но поскольку событие не могло быть "нацелено" на конкретный объект, у меня возникли проблемы. Я не уверен, что это лучшая практика, но, похоже, она работает хорошо для меня.