Myślę, że koncepcyjnie rozumiem delegatów C #, jednak staram się znaleźć przykład z prawdziwego świata, w którym byliby przydatni. Czy możesz podać odpowiedzi szczegółowo opisujące, w jaki sposób delegaci C # byli wykorzystywani w rzeczywistych aplikacjach i jakie problemy umożliwiły ci poruszanie się.
16
Odpowiedzi:
Kod GUI używa delegatów do obsługi zdarzeń, takich jak kliknięcia przycisków, ruchy okien. Korzystanie z pełnomocnika pozwala mieć funkcję wywoływaną za każdym razem, gdy nastąpi zdarzenie. Przykładem może być połączenie funkcji, która zapisuje dane do przycisku „Zapisz” na interfejsie. Kliknięcie przycisku powoduje skonfigurowanie funkcji zapisywania danych. Jest to przydatne w programowaniu GUI, ponieważ cały program może czekać na użytkownika, aby coś zrobił, a ty nie możesz wiedzieć, co zrobi w pierwszej kolejności. Korzystanie z delegatów pozwala na połączenie funkcji twojego programu z interfejsem użytkownika w taki sposób, aby użytkownik mógł robić rzeczy w dowolny sposób.
źródło
Linq używa parametrów
Func<T>
iAction<T>
deleguje w dowolnym miejscu jako parametry.Pozwalają one używać wyrażeń lambda jako parametrów i definiują akcję, która ma być podjęta jako część listy parametrów.
źródło
Praktycznie wszystko przy użyciu Wzorca Obserwatora , prawdopodobnie implementuje delegatów.
Przeczytaj opis, a prawdopodobnie wyobrazisz sobie scenariusze, w których byś ich użył. Obsługa zdarzeń GUI jest częstym przykładem.
źródło
Delegaci są cholernie przydatni w programowaniu asynchronicznym.
Masz klasę, która robi rzeczy asynchronicznie i ma wywołanie zwrotne. Możesz wywołać metodę delegowaną po wywołaniu zwrotnym - a implementacja klasy wykona logikę opisaną w metodzie delegowanej.
źródło
Delegaci są szczególnie przydatni jako rozwiązanie dla dziury w środkowym wzorze . Zasadniczo istnieje wiele przypadków, w których chcesz zapakować unikalny zestaw instrukcji do wspólnej grupy instrukcji. Jest to szczególnie trudne, jeśli instrukcje przed i po unikatowym bicie muszą współdzielić stan. W przypadku delegatów możesz po prostu przekazać delegata do funkcji. Funkcja wykonuje bit przed, wykonuje delegata, a następnie wykonuje bit później.
źródło
W „dawnych czasach” języków innych niż OOP, takich jak Fortran i C, niezwykle przydatne było, aby podprogram otrzymał argument, który był wskaźnikiem funkcji. Na przykład
qsort
funkcja działa z podaną przez użytkownika funkcją porównawczą. Istnieje wiele podprogramów rozwiązywania zwykłych równań różniczkowych lub optymalizacji funkcji i wszystkie one przyjmują wskaźniki funkcji jako argumenty.W systemach okienkowych wszystkie rodzaje wywołań zwrotnych mają ten sam wzór.
W Lisp, nawet we wczesnych dniach, istniało coś, co nazywano „argumentem funkcjonalnym” lub FUNARG, co było nie tylko funkcją, ale zawierało także kontekst pamięci, w którym mógł pamiętać i wchodzić w interakcje z częścią świata zewnętrznego.
Ta sama potrzeba istnieje w językach OOP, z wyjątkiem sytuacji, gdy przekazujesz adres funkcji, musisz także przekazać adres obiektu, którego funkcja jest metodą. To dwie rzeczy, które musisz przekazać. Tak więc delegat jest właśnie taki i pozwala na stosowanie tego starego dobrego wzorca.
źródło
Oto prosty przykład, który pokazuje, jak użyteczni mogą być delegaci w tworzeniu prostego kodu, który działa zgodnie z zasadą DRY. Pozwala także zachować kod bardzo blisko miejsca, w którym jest potrzebny.
Oto rzeczywisty przykład korzyści zapewnianej przez delegatów.
źródło
Moje pierwsze spotkanie z delegatami polegało na sprawdzeniu aktualizacji programu (Windows tworzy C # 3.5) poprzez pobranie pliku z mojej strony internetowej, ale aby uniknąć sprawdzania aktualizacji blokującej cały program, użyłem delegata i wątku, aby zrobić to asynchronicznie.
źródło
Widziałem ciekawe wdrożenia wzorca strategii, który skutecznie wykorzystuje delegatów. (tzn. strategia jest delegatem)
Ten, na który patrzyłem, dotyczył wyszukiwania ścieżek, gdzie algorytm do znalezienia ścieżki był delegatem, któremu można (ponownie) przypisać w czasie wykonywania, aby można było użyć różnych algorytmów (BFS vs. A * itp.)
źródło
Wiele klasycznych wzorców GoF można zaimplementować za pomocą delegatów: Na przykład, wzorzec polecenia, wzorzec gościa, wzorzec strategii, wzorzec fabryczny i wzorzec obserwatora można często zaimplementować za pomocą prostego delegata. Czasami klasa jest lepsza (np. Gdy polecenie wymaga nazwy lub obiekt strategii wymaga serializacji), ale w większości przypadków użycie
Action<...>
lubFunc<...>
jest o wiele bardziej eleganckie niż utworzenie dedykowanego interfejsu jednokierunkowego.źródło