Nie rozumiem delegacji - prośba o wytłumaczenie

0

Witam serdecznie.
Zacząłem uczyć się C#, wcześniej trochę pisałem w ASP MVC, ale nie zagłębiałem się we wszystko. Używałem tego i czytałem tylko o tym co jest mi potrzebne. Teraz wypożyczyłem książkę i uzupełniam braki, jednak stanąłem na delegacjach i mam z nimi problem, a mianowicie:

Napisałem prosty kod, aby je przetestować:

        delegate int delegacja(int a);

        public int dodawanie(int a)
        {
            return 1 + a;
        }

        public int odejmowanie(int a)
        {
            return 1 - a;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            delegacja del = new delegacja(dodawanie);
            del += odejmowanie;
            MessageBox.Show(del(2).ToString());
        }

Wszystko jest ok, ale :

  1. Po co dodawać do delegacji kolejne metody skoro wywołuje się tylko ta ostatnia?
  2. Po co mi w ogóle delegacja skoro mogę wywołać metodę, która mnie interesuje bez delegacji?

Proszę o pomoc.

1

Delegację możesz np użyć w celu przekopiowania danych/zmiennych z jednej formy na drugą.

4
  1. Zazwyczaj się nie dodaje - wyjątkiem są eventy które są specjalnym typem delegatów
    W dodatku nie masz racji - uruchomią się wszystkie funkcje, ale wynik dostaniesz tylko z jednej, dlatego też nie korzysta się z nich w ten sposób jeśli zwracają wartość. Jeśli natomiast przekazałbyś obiekt to każdy delegat po kolei mógłby zmienić jego wartość i dostałbyś na końcu wartość wynikową:
        public class A
        {
            public int Licznik { get; set; }
        }

        public delegate void delegacja(A a);

        public void dodawanie(A a)
        {
            a.Licznik = 1 + a.Licznik;
        }

        public void odejmowanie(A a)
        {
            a.Licznik = 1 - 2 * a.Licznik;
        }

        public void Run()
        {
            delegacja del = dodawanie;
            del += odejmowanie;
            A a = new A { Licznik = 5 };
            del(a);
            Console.WriteLine(a.Licznik.ToString());
        }
  1. Nie używa się ich w ten sposób po raz drugi
    Służą głównie do odwrócenia zależności - klasa wywołująca może przekazać metodę która klasa wykonawcza ma wykonać - w ten sposób klasa wykonawcza może robić coś sama nie wiedząc w jaki sposób to robi - sposób jest dostarczany z zewnątrz. Jest to wykorzystywane w wielu wzorcach projektowych, pomaga m.in. w problemach wzajemnych zależności referencji
1

wyjątkiem są eventy które są specjalnym typem delegatów

event ma się tak do delegata jak property do pola. to tak jakby się ktoś pytał po co są eventy i czym się różnią ;-)

1
nieznasz napisał(a):
  1. Po co mi w ogóle delegacja skoro mogę wywołać metodę, która mnie interesuje bez delegacji?

Wyobraź sobie, że masz 5 metod o takiej samej sygnaturze i chcesz zmierzyć czas wykonania każdej z nich. Jak to zrobisz?
Dzięki delegatom możesz napisać metodę, która będzie zawierała logikę mierzącą czas wykonania konkretnej metody, którą przyjmie w argumencie. Delegat to po prostu taki "wskaźnik na metodę".

Suchy Suchar napisał(a):
  1. Zazwyczaj się nie dodaje - wyjątkiem są eventy które są specjalnym typem delegatów

Delegat, któremu przypisano wiele metod, to multicast delegate. Event to nie jest specjalny typ delegatu tylko wbudowana w C# implementacja wzorca Obserwator, przy czym event musi mieć typ jakiegoś delegata.

0

Wiele mi się wyjaśniło, dziękuję wszystkim za pomoc, właśnie o taką formę pomocy mi chodziło!
Co do dodawania wielu metod do delegatów (multicast delegate) @suchy Suchar piszę, że raczej się nie dodaje, jak już to eventy, też co nie co o tym czytałem, jednak dzięki waszemu objaśnieniu znajduję całkiem rozsądne zastosowanie multicast delegate (tak mi się wydaję) np.:

Mam program, którego zadaniem jest odebranie produktu, opakowanie go, dodanie ceny i wysyłka. Tworzę delegate, któremu dodaje kolejne metody: odbierzProdukt, opakujProdukt, dodajCenę oraz wyślij. Zamiast kolejno wypisywać metody, mogę skorzystać z multicast delegate i cały proces związany z produktem odbędzie się automatycznie.

Wydaję mi się, że zrozumienie ich dogłębnie wyjdzie w praktyce. Jednak już jakiś zarys mam.
Dziękuję jeszcze raz, pozdrawiam !

3
nieznasz napisał(a):

dzięki waszemu objaśnieniu znajduję całkiem rozsądne zastosowanie multicast delegate (tak mi się wydaję) np.:

Mam program, którego zadaniem jest odebranie produktu, opakowanie go, dodanie ceny i wysyłka. Tworzę delegate, któremu dodaje kolejne metody: odbierzProdukt, opakujProdukt, dodajCenę oraz wyślij. Zamiast kolejno wypisywać metody, mogę skorzystać z multicast delegate i cały proces związany z produktem odbędzie się automatycznie.

to nie jest dobre podejście
po pierwsze - nic to nie daje - funkcje musisz dodać do delegata ręcznie, nie wnosi to żadnych korzyści w opisanym przypadku nad stworzeniem fasady która kolejno będzie odpalać te funkcje
po drugie - jest dziwne, osoba która będzie potem czytać taki kod może mieć chwilę WTF w głowie zanim zrozumie co się dzieje
po trzecie - jest trudne w debugowaniu - lista podpiętych funkcji nie jest jasno widoczna, odpalenie jednej linijki kodu spowoduje odpalenie wszystkich funkcji bez możliwości zatrzymania się na konkretnym etapie
po czwarte - jest sztywne - nie da się zmienić odpalanej funkcji podczas działania kodu - chcąc pominąć jeden etap można go wywalić, ale wstawienie z powrotem w to samo miejsce już jest trudne - lepiej wykorzystać metody szablonowe lub strategię
po piąte i najważniejsze - nie masz gwarancji że funkcje zostaną wykonane w kolejności dodania - nie jest to określone w specyfikacji, kolejność dodania funkcji do delegata nie musi być zapamiętywana i funkcje mogą równie dobrze być odpalane w losowej kolejności - to że działa teraz, nie znaczy że będzie działać w przyszłej wersji .NET

2

nie używaj tego na siłę, gdy dojdziesz do sytuacji gdzie przyda się wykorzystanie delegata to sam na to wpadniesz

1 użytkowników online, w tym zalogowanych: 0, gości: 1