Где использовать делегатов?

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

В PHP
В PHP
В большой кодовой базе с множеством различных компонентов классы, функции и константы могут иметь одинаковые имена. Это может привести к путанице и...
Принцип подстановки Лискова
Принцип подстановки Лискова
Принцип подстановки Лискова (LSP) - это принцип объектно-ориентированного программирования, который гласит, что объекты суперкласса должны иметь...
109
0
45 847
8
Перейти к ответу Данный вопрос помечен как решенный

Ответы 8

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

Быстрый поиск в Google нашел это http://en.wikipedia.org/wiki/Delegation_pattern. По сути, каждый раз, когда вы используете объект, который перенаправляет его вызовы другому объекту, вы делегируете его.

Ответ принят как подходящий

A delegate is a named type that defines a particular kind of method. Just as a class definition lays out all the members for the given kind of object it defines, the delegate lays out the method signature for the kind of method it defines.

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

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

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

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

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

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

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

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

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

У меня был проект, в котором использовался 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 (...), классом делегата, который содержит желаемую функцию представления времени как значение дополнительного поля и который делегирует все остальные запросы полей к исходному объекту подключения.

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

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

Я нашел большое применение делегатам, прочитав: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 (вместо passata), либо назначение функции Form 1 должно называться frm.pass Data (вместо frm.funData).

ethan 05.02.2018 20:16

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

General Scenario: When a head of state dies, the President of the United States typically does not have time to attend the funeral personally. Instead, he dispatches a delegate. Often this delegate is the Vice President, but sometimes the VP is unavailable and the President must send someone else, such as the Secretary of State or even the First Lady. He does not want to “hardwire” his delegated authority to a single person; he might delegate this responsibility to anyone who is able to execute the correct international protocol.

The President defines in advance what responsibility will be delegated (attend the funeral), what parameters will be passed (condolences, kind words), and what value he hopes to get back (good will). He then assigns a particular person to that delegated responsibility at “runtime” as the course of his presidency progresses.

In programming Scenario: You are often faced with situations where you need to execute a particular action, but you don’t know in advance which method, or even which object, you’ll want to call upon to execute it.

For Example: A button might not know which object or objects need to be notified. Rather than wiring the button to a particular object, you will connect the button to a delegate and then resolve that delegate to a particular method when the program executes.

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

Pacerier 06.11.2014 02:19

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

Anthony 28.01.2015 23:50

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

Martin Mulder 22.04.2015 11:36

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

JustJohn 29.06.2016 00:23

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

AminM 23.06.2017 00:18

Другие вопросы по теме