Gdzie używam delegatów? [Zamknięte]


109

Jakie są miejsca w prawdziwym świecie, które wymagają delegatów? Ciekaw jestem, jakie sytuacje lub wzorce są obecne, w których ta metoda jest najlepszym rozwiązaniem. Nie jest wymagany kod.

Odpowiedzi:


33

Delegat to nazwany typ, który definiuje określony rodzaj metody. Tak jak definicja klasy określa wszystkie składowe dla danego rodzaju obiektu, który definiuje, delegat kładzie podpis metody dla rodzaju metody, którą definiuje.

Na podstawie tej instrukcji delegat jest wskaźnikiem funkcji i definiuje, jak ta funkcja wygląda.

Doskonałym przykładem rzeczywistego zastosowania delegata jest Predykat . W przykładzie z linku zauważysz, że Array.Find pobiera tablicę do wyszukiwania, a następnie predykat do obsługi kryteriów wyszukiwania. W tym przypadku przekazuje metodę ProductGT10, która jest zgodna z sygnaturą Predicate.


154

Jak stwierdzono w sekcji „Nauka języka C # 3.0: opanuj podstawy języka C # 3.0”

Scenariusz ogólny: gdy umiera głowa państwa, prezydent Stanów Zjednoczonych zazwyczaj nie ma czasu, aby osobiście uczestniczyć w pogrzebie. Zamiast tego wysyła delegata. Często ten delegat jest wiceprezydentem, ale czasami wiceprezes jest niedostępny, a prezydent musi wysłać kogoś innego, na przykład sekretarza stanu lub nawet pierwszą damę. Nie chce „podłączyć” swojej delegowanej władzy do jednej osoby; mógłby przekazać tę odpowiedzialność każdemu, kto jest w stanie wykonać właściwy protokół międzynarodowy.

Prezydent z góry określa, jaka odpowiedzialność zostanie przekazana (uczestnictwo w pogrzebie), jakie parametry zostaną przekazane (kondolencje, miłe słowa) i jaką wartość ma nadzieję odzyskać (dobra wola). Następnie przydziela określoną osobę do tej delegowanej odpowiedzialności na „czas wykonywania” w miarę postępu jego prezydentury.

Scenariusz programowania: często masz do czynienia z sytuacjami, w których musisz wykonać określoną akcję, ale nie wiesz z góry, którą metodę lub nawet obiekt chcesz wywołać, aby ją wykonać.

Na przykład: przycisk może nie wiedzieć, który obiekt lub obiekty wymagają powiadomienia. Zamiast łączyć przycisk z określonym obiektem, należy połączyć przycisk z delegatem, a następnie rozwiązać tego delegata z określoną metodą, gdy program jest wykonywany.


1
Dlaczego więc po prostu nie użyć anonimowych funkcji / lambd?
Pacerier

5
@Pacerier To jest późna odpowiedź i być może znalazłeś odpowiedź, ale ze względu na innych czytelników, którzy ją znaleźli: anonimowa funkcja jest rodzajem delegata.
Anthony

10
@ Anthony + Pacerier: Anoymous metoda NIE jest delegatem. Metoda anonimowa to fragment kodu. Delegat to wskaźnik wskazujący na ten fragment kodu. Nie można mieć anonimowej metody bez wskazującego na nią delegata, w przeciwnym razie nigdy nie zostałaby wywołana. Lambda jest operatorem używanym do konstruowania wyrażeń lambda. Wyrażenia lambda w większości skutkują anonimowymi metodami, na które wskaże ... delegat.
Martin Mulder

Głupi mnie, ale po prostu utworzyłbym instrukcję If ElseIf, gdybym nie wiedział, do czego służy, gdy przycisk został naciśnięty. Powiedziałem, że jestem głupi.
JustJohn

@Pacerier anonimowa metoda wprowadzona w C # 2.0 i Lambda wprowadzona w C # 3.0, gdyby Lambda została wprowadzona jako pierwsza, nigdy nie byłoby metod anonimowych, a nawet delegatów!
AminM

18

Jednym z typowych zastosowań delegatów dla list ogólnych są delegaci akcji (lub ich anonimowe odpowiedniki) do tworzenia jednowierszowych operacji foreach:

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

Uważam również, że delegat predykatu jest całkiem przydatny w wyszukiwaniu lub przycinaniu listy:

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

Wiem, że powiedziałeś, że kod nie jest wymagany, ale łatwiej mi jest wyrazić jego użyteczność za pomocą kodu. :)


13

Powiązanie zdarzeń z programami obsługi zdarzeń jest zwykle pierwszym wprowadzeniem do delegatów ... Możesz nawet nie wiedzieć, że ich używasz, ponieważ delegat jest opakowany w klasę EventHandler.


5

Jeśli chcesz zobaczyć, jak wzorzec Delegate jest używany w prawdziwym kodzie, nie szukaj dalej niż Cocoa w systemie Mac OS X. Cocoa to preferowany przez Apple zestaw narzędzi interfejsu użytkownika do programowania w systemie Mac OS X i jest zakodowany w celu C. zaprojektowany w taki sposób, że każdy komponent interfejsu użytkownika ma być rozszerzany poprzez delegowanie, a nie tworzenie podklas lub w inny sposób.

Aby uzyskać więcej informacji, polecam sprawdzić, co Apple ma do powiedzenia na temat delegatów tutaj .


5

Miałem projekt, który korzystał z win32 Python.

Z różnych powodów niektóre moduły używały odbc.py do dostępu do DB, a inne - pyodbc.py.

Wystąpił problem, gdy funkcja musiała być używana przez oba rodzaje modułów. Miał obiekt połączenia przekazany do niego jako argument, ale potem musiał wiedzieć, czy użyć dbi.dbiDate czy datetime do reprezentowania czasów.

Było to spowodowane tym, że odbc.py oczekiwał, jako wartości w instrukcjach SQL, dat jako dbi.dbiDate, podczas gdy pyodbc.py oczekiwano wartości datetime.

Kolejną komplikacją było to, że obiekty połączeń utworzone przez odbc.py i pyodbc.py nie pozwalały na ustawienie dodatkowych pól.

Moim rozwiązaniem było zawinięcie obiektów połączeń zwróconych przez odbc.odbc (...) i pyodbc.pyodbc (...) przez klasę delegatów, która zawiera żądaną funkcję reprezentacji czasu jako wartość dodatkowego pola i która deleguje wszystkie inne żądania pól do oryginalnego obiektu połączenia.


5

Miałem to samo pytanie co Ty i poszedłem na tę stronę po odpowiedź.

Najwyraźniej nie zrozumiałem tego lepiej, chociaż przejrzałem przykłady w tym wątku.

Znalazłem świetne zastosowanie dla delegatów teraz, gdy przeczytałem: http://www.c-sharpcorner.com/UploadFile/thiagu304/passdata05172006234318PM/passdata.aspx

Może się to wydawać bardziej oczywiste dla nowych użytkowników, ponieważ przekazywanie wartości przez Forms jest znacznie bardziej skomplikowane niż witryny ASP.NET z POST / GET (QueryString).

Zasadniczo definiujesz delegata, który przyjmuje tekst TextBox ” jako parametry.

// Formularz 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();
}

// PODSUMOWANIE: Zdefiniuj delegata, utwórz nową klasę Form2, przypisz funkcję funData () do delegata, przekaż swoje textBox delegatowi. Pokaż formularz.

// Form2

public void passData(TextBox txtForm1)
{

     label1.Text = txtForm1.Text;
}

// PODSUMOWANIE: Po prostu weź TextBox txtForm1 jako parametry (zgodnie z definicją w delegacie) i przypisz tekst etykiety do tekstu textBox.

Mam nadzieję, że to oświeci niektórych przydatnych dla delegatów :) ..


Albo metoda klasy Form2 musi mieć nazwę funData (zamiast passData), albo przypisanie funkcji Form1 musi mieć nazwę frm.passData (zamiast frm.funData).
ethan

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.