Де я можу використовувати делегатів? [зачинено]


109

Які реальні місця світу вимагають делегатів? Мені цікаво, які ситуації чи закономірності існують, коли цей метод є найкращим рішенням. Не потрібен код.

Відповіді:


33

Делегат - це названий тип, який визначає певний тип методу. Так само, як визначення класу викладає всіх членів для даного виду об'єкта, який він визначає, делегат викладає підпис методу для типу методу, який він визначає.

На основі цього твердження делегат - це вказівник функції, який визначає, як виглядає ця функція.

Прекрасним прикладом для застосування делегата в реальному світі є предикат . На прикладі посилання ви помітите, що Array.Find бере масив для пошуку, а потім присудок для обробки критеріїв, що потрібно знайти. У цьому випадку він передає метод ProductGT10, який відповідає підпису Predicate.


154

Як зазначено у "Навчанні C # 3.0: оволодіння основами C # 3.0"

Загальний сценарій: Коли глава держави помирає, президент США, як правило, не встигає особисто відвідувати похорон. Натомість він відправляє делегата. Часто цей делегат є віце-президентом, але іноді ВП є недоступним, і Президент повинен надіслати когось іншого, наприклад Державного секретаря чи навіть Першу леді. Він не хоче "переводити" свої делеговані повноваження на одну особу; він може делегувати цю відповідальність тому, хто може виконати правильний міжнародний протокол.

Президент заздалегідь визначає, яка відповідальність буде делегована (відвідуйте похорон), які параметри будуть передані (співчуття, добрі слова) та яку цінність він сподівається повернути (добра воля). Потім він привласнює конкретну особу до цієї делегованої відповідальності під час "виконання" в міру просування курсу його президентства.

Сценарій програмування: Ви часто стикаєтеся з ситуаціями, коли вам потрібно виконати певну дію, але ви не знаєте заздалегідь, який метод чи навіть який об’єкт, вам потрібно буде закликати його виконати.

Наприклад: кнопка може не знати, про який об’єкт або об’єкти потрібно повідомити. Замість того, щоб підключити кнопку до певного об'єкта, ви підключите кнопку до делегата, а потім вирішите цей делегат до певного методу при виконанні програми.


1
Чому б тоді просто не використовувати анонімні функції / лямбда?
Пейс’єр

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

Якщо вам цікаво побачити, як використовується шаблон «Делегат» у реальному коді, не дивіться далі, ніж Какао на Mac OS X. Какао - це вподобаний інструментарій інтерфейсу Apple для програмування під Mac OS X і кодується у «Цілі C.» розроблений таким чином, що кожен компонент інтерфейсу призначений для розширення шляхом делегування, а не підкласифікації чи інших засобів.

Для отримання додаткової інформації я рекомендую перевірити, що Apple може сказати про делегатів тут .


5

У мене був проект, який використовував Win32 Python.

Через різні причини деякі модулі використовували odbc.py для доступу до БД, а інші модулі - pyodbc.py.

Виникла проблема, коли функцію потрібно було використовувати для обох типів модулів. Він мав об'єкт з'єднання, переданий йому в якості аргументу, але тоді він повинен знати, чи використовувати dbi.dbiDate або datetime для подання часу.

Це сталося тому, що очікуваний odbc.py, як значення в операторах SQL, датується як dbi.dbiDate, тоді як pyodbc.py очікувані значення дати.

Ще одним ускладненням було те, що об'єкти з'єднання, створені odbc.py та pyodbc.py, не дозволяють встановлювати додаткові поля.

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


5

У мене було те саме питання, що і у вас, і я зайшов на цей сайт, щоб відповісти.

Мабуть, я не зрозумів це краще, хоча я проглянув приклади цієї теми.

Тепер я прочитав: http://www.c-sharpcorner.com/UploadFile/thiagu304/passdata05172006234318PM/passdata.aspx.

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

В основному ви визначаєте делегата, який приймає "TextBox текст " як параметри.

// Форма1

// 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 () для делегації, передайте ваш textBox делегату. Покажіть форму.

// 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.