Страницы

Поиск по вопросам

четверг, 28 ноября 2019 г.

Что такое делегат в языке С#?

#c_sharp #c_sharp_faq #делегаты


Объясните простым, человеческим языком, кто такой и зачем нужен делегат в ООП вообще
и в С# в частности?
    


Ответы

Ответ 1



Делегат — это объектно-ориентированный способ работы с методом как с переменной. Его более привычный аналог — указатель на функцию, функтор, или даже просто вектор прерывания (спасибо @rdorn за подсказку). Делегат представляет собой тип, соответствующий определённой сигнатуре функции. Объявив переменную делегатного типа, вы можете записать в неё статический или нестатический метод, передать его как аргумент куда-либо, и вызвать. Классический пример использования делегатов — сортировка списка объектов по значению какого-либо поля. Вы передаёте в сортирующий метод делегат, который по объекту вычисляет ключ сортировки, то есть, вытаскивает значение поля.

Ответ 2



Из справки на MSDN Делегаты (Руководство по программированию на C#): Делегат — это тип, представляющий ссылки на методы с конкретным списком параметров и возвращаемым типом. При создании экземпляра делегата этот экземпляр можно связать с любым методом с совместимой сигнатурой и возвращаемым типом. Метод можно вызвать (активировать) с помощью экземпляра делегата. Добавлю своими словами: делегаты можно назвать особыми типами с кодом, генерируемым на этапе выполнения. Также можно сказать, что это своего рода указатели на методы. Вызов делегатов выполняется в том же потоке через метод, вызванный с использованием делегата, причем исключения бросаются так же, как будто метод был вызван напрямую. Вызов делегата с одним методом равносилен обычному вызову метода. Один делегат может вызвать много методов (если подписаны на несколько методов). Касаемо ООП - как уже было сказано, это объектно-ориентированный способ работы с методом. Вообще, тема ООП достаточно большая, поэтому тут только вскользь. Делегат - это такой же тип, как к примеру класс или интерфейс, он может определяться либо внутри класса, либо вне, в пределах пространства имен. На ruSO C#-делегаты достаточно популярная тема, вопросы и ответы на которую имеются, для изучения приведу пару примеров: Делегаты и их экземпляры Как пользоваться делегатами? Делегаты C#. Invoke c# Делегаты - плюсы и минусы Когда обычно нужно использовать делегаты?

Ответ 3



Уже 2 ответа даны. Я добавлю третий вариант, более человечный :) Делегат - лучше всего вспомнить о таком слове как Представитель. Это слово будет синонимом или, если хотите, переводом на русский яз. Еще можно вспомнить о слове Депутат. Короче, представитель, который представляет в качестве себя одного любимого многих. Депутат представляет выборщиков, много выборщиков. Делегат в языке C# - представляет или может представлять много методов. Этакое отношение один-ко-многим. Делегат похож на переменную, которая может ссылаться на один или больше методов с одинаковой сигнатурой и возвращаемым типом. После создания делегата с нужной сигнатурой, вы можете подписывать (присоединять к списку вызова этого делегата с помощью операции +=) методы или отписывать (удалять из списка вызова операцией -=) методы. В дальнейшем использовав вызов делегата, вы производите вызов всех методов, которые ранее были в списке вызова. Еще одна аналогия - список e-mail рассылки - отправка одного письма сразу многим адресатам. Про использование в ООП: на делегатах основаны события, с помощью делегатов можно создавать анонимные методы (методы без имени), ну и см. ответ уважаемого @VladD.

Ответ 4



Я думаю что остальные излишне сложно написали... Если просто и в двух словах: Делегат - это просто обьект хранящий ссылку(и) на метод(ы). И на примере использования: Обьявляем делегат: delegate int Mydel(int x, int y); Обьявляем метод, который может быть подписан на делегат. Пример кодом: static int Sum(int x, int y) { return x + y; } Этот метод должен соответствовать: Иметь такую же сигнатуру как сам делегат (входные параметры) Возвращать такой же тип данных как и делегат . Мой код, как видно, соответствует этому. Использование делегата: // обьявил переменную делегата и подписал метод Sum Mydel sumDelegate = Sum; //вызвал метод Sum через sumDelegate int result = sumDelegate(10, 5); Что нужно иметь ввиду: Один делегат может вызвать много методов (если подписаны на несколько методов). (подписывать через += и отписывать через -= ) Вызов делегата делается в том же потоке, в котором находится метод, из которого его вызвали. Это значит, что если у вас есть 2 потока в программе, и нужно вызвать метод, который делает что-то из UI потока, нужно вызвать BeginInvoke. Как-то так: Dispatcher.BeginInvoke(sumDelegate(10, 5)); Еще есть предопределенные делегаты Action и Func. Лично я предпочитаю пользоваться именно ими. Еще есть довольно родственное понятие event. Event- ы основаны на делегатах. Про разницу между ними можно почитать вот здесь: Event и delegate: в чем отличие?

Комментариев нет:

Отправить комментарий