Где использовать делегатов? [закрыто]


109

Какие места в реальном мире требуют делегатов? Мне любопытно, какие ситуации или шаблоны присутствуют, когда этот метод является лучшим решением. Код не требуется.

Ответы:


33

Делегат - это именованный тип, который определяет конкретный вид метода. Подобно тому, как определение класса содержит все члены для данного типа объекта, который он определяет, делегат устанавливает сигнатуру метода для того типа метода, который он определяет.

Основываясь на этом утверждении, делегат является указателем на функцию и определяет, как эта функция выглядит.

Отличным примером реального приложения делегата является Predicate . В примере по ссылке вы заметите, что Array.Find принимает массив для поиска, а затем предикат для обработки критериев того, что нужно найти. В этом случае он передает метод ProductGT10, который соответствует сигнатуре предиката.


154

Как указано в статье «Изучение C # 3.0: освоение основ C # 3.0»

Общий сценарий: когда умирает глава государства, президент Соединенных Штатов обычно не имеет времени лично присутствовать на похоронах. Вместо этого он отправляет делегата. Часто этим делегатом является вице-президент, но иногда вице-президент недоступен, и президент должен послать кого-нибудь еще, например, государственного секретаря или даже первой леди. Он не хочет «привязать» делегированные ему полномочия к одному человеку; он мог бы делегировать эту ответственность любому, кто способен выполнить правильный международный протокол.

Президент заранее определяет, какие обязанности будут делегированы (присутствовать на похоронах), какие параметры будут переданы (соболезнования, добрые слова) и какую ценность он надеется получить обратно (добрая воля). Затем он назначает конкретному человеку эту делегированную ответственность «во время исполнения» по мере продвижения своего президентства.

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

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


1
Почему бы тогда просто не использовать анонимные функции / лямбды?
Pacerier 05

5
@Pacerier Это запоздалый ответ, и вы, возможно, уже нашли ответ, но ради других читателей, которые его находят: анонимная функция - это тип делегата.
Энтони

10
@ Anthony + Pacerier: анонимный метод НЕ является делегатом. Анонимный метод - это кусок кода. Делегат - это указатель, который указывает на этот фрагмент кода. У вас не может быть анонимного метода без указывающего на него делегата, иначе он никогда не будет вызван. Лямбда - это оператор, используемый для построения лямбда-выражений. Лямбда-выражения в основном приводят к анонимным методам, на которые будет указывать ... делегат.
Мартин Малдер

Глупо, но я бы просто создал оператор If ElseIf, если бы не знал, как его использовать при нажатии кнопки. Я сказал глупо.
JustJohn

Анонимный метод @Pacerier, представленный в C # 2.0 и Lambda, представленный в C # 3.0, если бы Lambda была введена первой, анонимных методов и даже делегатов никогда бы не было!
AminM

18

Одним из распространенных способов использования делегатов для общих списков является использование делегатов Action (или его анонимного эквивалента) для создания однострочной операции foreach:

myList.Foreach( i => i.DoSomething());

Я также считаю, что делегат Predicate весьма полезен при поиске или сокращении списка:

myList.FindAll( i => i.Name == "Bob");    
myList.RemoveAll( i => i.Name == "Bob");

Я знаю, что вы сказали, что код не требуется, но мне легче выразить его полезность через код. :)


13

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


5

Если вам интересно узнать, как шаблон Delegate используется в реальном коде, не ищите ничего, кроме Cocoa в Mac OS X. Cocoa - это предпочтительный набор инструментов пользовательского интерфейса Apple для программирования под Mac OS X и кодируется в Objective C. разработан таким образом, что каждый компонент пользовательского интерфейса предназначен для расширения посредством делегирования, а не подкласса или других средств.

Для получения дополнительной информации я рекомендую проверить, что Apple говорит о делегатах здесь .


5

У меня был проект, в котором использовался Win32 Python.

По разным причинам одни модули использовали odbc.py для доступа к БД, а другие - pyodbc.py.

Возникла проблема, когда функция должна была использоваться обоими типами модулей. В качестве аргумента ему был передан объект подключения, но затем он должен был знать, использовать ли dbi.dbiDate или datetime для представления времени.

Это произошло потому, что odbc.py ожидал, как значения в операторах SQL, даты как dbi.dbiDate, тогда как pyodbc.py ожидаемые значения datetime.

Еще одна сложность заключалась в том, что объекты подключения, созданные odbc.py и pyodbc.py, не позволяли устанавливать дополнительные поля.

Мое решение заключалось в том, чтобы обернуть объекты соединения, возвращаемые odbc.odbc (...) и pyodbc.pyodbc (...), классом делегата, который содержит желаемую функцию представления времени как значение дополнительного поля и делегирует все остальные запросы полей к исходному объекту подключения.


5

У меня был тот же вопрос, что и у вас, и я зашел на этот сайт за ответом.

Видимо, я не понял этого лучше, хотя бегло просмотрел примеры в этой ветке.

Я нашел большое применение делегатам, прочитав: http://www.c-sharpcorner.com/UploadFile/thiagu304/passdata05172006234318PM/passdata.aspx

Это может показаться более очевидным для новых пользователей, потому что Forms намного сложнее передавать значения, чем веб-сайты ASP.NET с POST / GET (QueryString) ..

В основном вы определяете делегата, который принимает « текст TextBox » в качестве параметров.

// Form1

// Class Property Definition
public delegate void delPassData(TextBox text);


// Click Handler
private void btnSend_Click(object sender, System.EventArgs e)
{
     Form2 frm= new Form2();
     delPassData del=new delPassData(frm.funData);
     del(this.textBox1);
     frm.Show();
}

// РЕЗЮМЕ: определение делегата, создание экземпляра нового класса Form2, назначение функции funData () делегату, передача вашего текстового поля делегату. Покажи форму.

// Form2

public void passData(TextBox txtForm1)
{

     label1.Text = txtForm1.Text;
}

// РЕЗЮМЕ: просто возьмите TextBox txtForm1 в качестве параметров (как определено в вашем делегате) и назначьте текст метки тексту textBox.

Я надеюсь, что это поможет пролить свет на делегатов :) ..


Либо метод класса Form2 должен называться funData (вместо passData), либо назначение функции Form1 необходимо называть frm.passData (вместо frm.funData).
Итан

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.