Nie rozumiem delegacji - prośba o wytłumaczenie

2015-02-10 12:13
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.

jako tag podawaj nazwę języka, to zdecydowanie więcej mówi niż "delegate", szczególnie, że w tytule ładnie wyjaśniłeś o co chodzi - dzek69 2015-02-10 12:26
Będę o tym pamiętał, dzięki - nieznasz 2015-02-10 12:33

Pozostało 580 znaków

2015-02-10 12:29
1

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


Przyjmę zlecenia / projekty do wykonania w c#. Zainteresowanych zapraszam do konwersacji na PW.
Mógłbyś podać przykład, bardziej sprecyzować wypowiedź. - nieznasz 2015-02-10 12:36
Jestem w podróży, odpowiadam z telefonu. Ale załóżmy użytkownik loguje sie do programu a ty za pomocą logunu i hasła pobierasz jego "id" z bazy w następnej formie chcesz by użytkownik miał tam jakiś swój profil z prawami określonymi w bazie, to wysyłasz pobrane "id" użytkownika w zmiennej za pomocą delegatów. Mam nadzieję ze w miarę jasno naświetliłem problem. - wojas666 2015-02-10 13:09
@wojas666 możesz bardziej szczegółowo opisać jaka jest korzyść z zastosowania do tego celu delegatu? Sam teraz przepisuje/poprawiam swoj program w ktorym wlasnie w pierwszym oknie logowania z loginu i hasla pobieram "id" zalogowanego i to "id" ale przez zwyklego "int'a" przekazuje do budowy wlasciwego okna programu i na podsawie "int id" zalogowanego uzytkownika pobieram z bazy uprawnienia tego uzytkownika i w oparciu o te uprawnienia buduje menu w oknie wlasciwym. Jakbys wyjasnil dlaczego lepiej jest to robic delegatem to bym to moze wlasnie tak przerobil. - Varran 2015-02-11 13:11

Pozostało 580 znaków

2015-02-10 12:47
2015-02-10 13:13
Suchy Suchar
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

Pozostało 580 znaków

2015-02-10 13:46
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ą ;-)

Hmm... Ale skąd taka analogia? Ja bym powiedział raczej, że event ma się do delegata tak, jak metoda do typu albo klasa do interfejsu. - somekind 2015-02-10 14:21
rozumiesz słowo "delegat" jako typ, ja użyłem go w zaczeniu "pole typu delegatowego". chodzi mi o to że event to takie "delegatowe property" które może być trywialnym opakowaniem na prywatne pole (delegata), a może mieć niestandardowo oprogramowane akcesory add i remove. - Azarien 2015-02-10 14:26
Ok, teraz to bardziej zrozumiałe. - somekind 2015-02-10 14:33

Pozostało 580 znaków

2015-02-10 14:30
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.


"HUMAN BEINGS MAKE LIFE SO INTERESTING. DO YOU KNOW, THAT IN A UNIVERSE SO FULL OF WONDERS, THEY HAVE MANAGED TO INVENT BOREDOM."
edytowany 1x, ostatnio: somekind, 2015-02-10 14:33

Pozostało 580 znaków

2015-02-11 09:49
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 !

Pozostało 580 znaków

2015-02-11 10:05
Suchy Suchar
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

Jestem pod wrażeniem wiedzy ! Muszę się jeszcze wiele nauczyć, świetna wypowiedź! Dzięki - nieznasz 2015-02-11 11:10

Pozostało 580 znaków

2015-02-11 10:06
Suchy Suchar
2

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

Pozostało 580 znaków

Liczba odpowiedzi na stronę

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