Czym jest Delegat? [zamknięte]

Jestem zdezorientowany, że jaka jest rzeczywista rola delegata? Zadawano mi to pytanie wiele razy w moich wywiadach, ale nie sądzę, aby ankieterzy byli zadowoleni z mojej odpowiedzi.

Czy ktoś może mi podać najlepszą definicję, w jednym zdaniu, z praktycznym przykładem ?

Thanks

 130
Author: Naveed, 2010-01-11

13 answers

Lubię myśleć o delegacie jako o "wskaźniku do funkcji". To sięga czasów C, ale pomysł nadal jest aktualny.

Chodzi o to, że musisz być w stanie wywołać fragment kodu, ale ten fragment kodu, który chcesz wywołać, nie jest znany do czasu uruchomienia. Więc używasz do tego celu "delegata". Delegaci przydają się w takich sytuacjach, jak obsługa zdarzeń i takie, w których robisz różne rzeczy na podstawie różnych wydarzeń, na przykład.

Oto odniesienie do C# możesz spojrzeć na:

W C#, na przykład, powiedzmy, że mieliśmy obliczenia, które chcieliśmy wykonać i chcieliśmy użyć innej metody obliczeń, której nie znamy do czasu uruchomienia. Więc możemy mieć kilka metod obliczeniowych, takich jak ta:

public static double CalcTotalMethod1(double amt)
{
    return amt * .014;
}

public static double CalcTotalMethod2(double amt)
{
    return amt * .056 + 42.43;
}

Możemy zadeklarować podpis delegata w następujący sposób:

public delegate double calcTotalDelegate(double amt);

I wtedy możemy zadeklarować metodę, która przyjmuje delegata jako parametr taki jak:

public static double CalcMyTotal(double amt, calcTotalDelegate calcTotal)
{
    return calcTotal(amt);
}

I możemy wywołać metodę CalcMyTotal przekazującą w metodzie delegata możemy chciał użyć.

double tot1 = CalcMyTotal(100.34, CalcTotalMethod1);
double tot2 = CalcMyTotal(100.34, CalcTotalMethod2);
Console.WriteLine(tot1);
Console.WriteLine(tot2);
 148
Author: dcp,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-02 11:01:38

Delegat jest po prostu wskaźnikiem funkcji.
po prostu przypisujesz metodę, którą chcesz uruchomić swojego delegata. następnie w kodzie można wywołać tę metodę poprzez Invoke.

Jakiś kod do zademonstrowania (napisał to z pamięci więc składnia może być wyłączona)

delegate void delMyDelegate(object o);

private void MethodToExecute1(object o)
{
    // do something with object
}

private void MethodToExecute2(object o)
{
    // do something else with object
}

private void DoSomethingToList(delMyDelegate methodToRun)
{
    foreach(object o in myList)
        methodToRun.Invoke(o);
}

public void ApplyMethodsToList()
{
    DoSomethingToList(MethodToExecute1);
    DoSomethingToList(MethodToExecute2);
}
 16
Author: Mladen Prajdic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-11 19:28:03

Taken from here

Q czym są delegaci?
A gdy obiekt otrzymuje żądanie, może on sam obsłużyć żądanie lub przekazać żądanie innemu obiektowi w celu wykonania pracy. Jeśli obiekt zdecyduje się przekazać żądanie dalej, mówisz, że obiekt przekazał odpowiedzialność za obsługę żądania drugiemu obiektowi.

Lub, jako prosty pseudo przykład: coś wysyła żądanie do object1. object1 Prośba i sama w sobie o object2 -- delegat. object2 przetwarza żądanie i wykonuje pewną pracę. (Uwaga: powyższy link podaje dobre przykłady)

 13
Author: Anthony Forloney,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-11 19:34:52

Pomyśl o delegacie jako o uproszczonej implementacji wzorca poleceń.

 4
Author: Vitaliy Liptchinsky,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-11 19:32:23

Delegat jest obiektem, który może odnosić się do metody. Tak więc, kiedy tworzymy delegata, tworzymy obiekt, który może zawierać odniesienie do metody. Ponadto metoda może być wywołana przez to odniesienie. W ten sposób delegat może wywołać metodę, do której się odnosi. Główną zaletą delegata jest to, że pozwala nam określić wywołanie metody, ale faktycznie wywołana metoda jest określana w czasie wykonywania, a nie w czasie kompilacji.

Proste Delegat

Declaration of delegate:
delegate-modifier delegate return-type delegate-name(parameters)
Implementation of delegate:
Delegate-name delegate-object=new Delegate-name(method of class)

Http://knowpacific.wordpress.com/2012/01/26/delegate/

 3
Author: Sandeep Shekhawat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-06 06:31:49

Tutaj zamierzam wyjaśnić delegatów, delegatów multicast i ich wykorzystanie.. Delegat jest typem, który przechowuje odniesienie do metody(metod) w obiekcie. Jest również określany jako wskaźnik funkcji bezpieczeństwa typu. Możemy powiedzieć, że delegat jest typem, który definiuje podpis metody.

Kiedy tworzysz instancję delegata, możesz powiązać jego instancję z dowolną metodą ze zgodnym podpisem. Metodę można wywołać (lub wywołać) za pośrednictwem instancji delegata. Delegaci służą do przekazywania metod jako argumenty do innych metod. Procedury obsługi zdarzeń to nic innego jak metody wywoływane przez delegatów. Zalety korzystania z delegatów to, Kodowanie wywołania metody od rozmówcy Efektywne wykorzystanie delegata poprawia wydajność aplikacji Używany do wywołania metody asynchronicznie. Istnieją pewne właściwości delegatów

Delegates are like C++ function pointers but are type safe.
Delegates allow methods to be passed as parameters.
Delegates can be used to define callback methods.
Delegates can be chained together; for example, multiple methods can be called on a single event.
Methods do not have to match the delegate signature exactly.

Public delegate type_of_delegate delegate_name () / / Declaration

You can use delegates without parameters or with parameter list
If you are referring to the method with some data type then the delegate which you are declaring should be in the same format. This is why it is referred to as type safe function pointer. Here I am giving an example with String.

Poniższy przykład pokazuje delegata działanie:

    namespace MyDelegate
    {
        class Program
        {
            private delegate void Show(string s);


            // Create a method for a delegate.
            public static void MyDelegateMethod(string me

ssage)
        {
            System.Console.WriteLine(message);
        }

        static void Main(string[] args)
        {
            Show p = MyDelegateMethod;
            p("My Delegate");
            p.Invoke("My Delegate");
            System.Console.ReadLine();
        }
    }
}

Czym jest Multicast Delegate?

Jest to delegat, który posiada odniesienie do więcej niż jednej metody. Delegaty multicastu muszą zawierać tylko metody, które zwracają void, w przeciwnym razie istnieje wyjątek run-time.

 delegate void MyMulticastDelegate(int i, string s);
 Class Class2
 {
  static void MyFirstDelegateMethod(int i, string s)
  {
    Console.WriteLine("My First Method");
  }

  static void MySecondDelegateMethod(int i, string s)
  {
    Console.WriteLine("My Second Method");
  }

  static void Main(string[] args)
  {
    MyMulticastDelegate Method= new MyMulticastDelegate(MyFirstDelegateMethod);
    Method+= new MyMulticastDelegate (MySecondDelegateMethod);
    Method(1,"Hi");             // Calling 2 Methodscalled
    Method-= new MyMulticastDelegate (MyFirstDelegateMethod);
    Method(2,"Hi");             //Only 2nd Method calling
  }
}

Tutaj Delegat jest dodawany za pomocą operatora + = i usuwany za pomocą operatora -=.

Typy delegatów pochodzą z klasy Delegatów w. NET Framework. Typy delegatów są zapieczętowane-nie można ich wyprowadzać. Ponieważ instancyjny delegat jest obiektem, może być przekazany jako parametr lub przypisany do właściwości. Pozwala to metodzie na zaakceptowanie delegata jako parametru i wywołanie go w późniejszym czasie. Jest to znane jako asynchroniczne wywołanie zwrotne.

 2
Author: Jom George,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-22 10:58:21

Świetne wyjaśnienie i praktyczna implementacja wzorca delegata można znaleźć w kolekcjach Google Forwarding (również wzór dekoratora).

 1
Author: Carl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-11 22:42:25

W komunikacji zdarzeń nadawca nie wie, który obiekt obsłuży Zdarzenie. Delegate to typ, który zawiera odniesienie do metody. Delegat ma podpis i zawiera odniesienie do metody, która pasuje do jego podpisu Delegat jest więc jak wskaźnik funkcji typu safe.

Button1.Kliknij + = nowy System.EventHandler (button1_Click) System.EventHandler jest zadeklarowany jako delegat tutaj W zdarzeniach. NET działa na zasadzie delegata (jak kliknięcie przycisku)

Delegat jest używany, gdy nie wiedzieć, który Kod wywołać w czasie wykonywania Tak więc w tym czasie Delegat jest używany do obsługi zdarzeń

Http://msdn.microsoft.com/en-us/library/ms173171 (v=vs.80). aspx

 1
Author: Yogesh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-22 13:03:32

A delegate object jest obiektem, który inny obiekt konsultuje, gdy coś dzieje się w tym obiekcie. Na na przykład, twój pracownik naprawy jest Twoim delegatem, jeśli coś stanie się z Twoim samochodem. idziesz do naprawcy i prosisz go, aby naprawił samochód dla ciebie (chociaż niektórzy wolą sam naprawiać samochód, w takim przypadku są ich własnym delegatem dla swojego samochodu).

 1
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-30 06:31:31

Delegat jest obiektem reprezentującym wskaźnik do funkcji. Nie jest to jednak zwykły wskaźnik funkcji, ponieważ:

1) Jest Zorientowane Obiektowo

2) jest bezpieczny, tzn. może wskazywać tylko na metodę i nie można odczytać surowego adresu pamięci, na który wskazuje

3) jest mocno wpisany. Może wskazywać tylko metody, które pasują do jego sygnatur.

4) może wskazywać na więcej niż jedną metodę w tym samym czasie.

 1
Author: Water Cooler v2,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-22 15:39:16

Delegatów używa się głównie przy zdarzeniach.

Potrzeba jest:

Nie chcesz wykonywać kawałka kodu w czasie uruchamiania programu. Po uruchomieniu programu chcesz wykonać ten fragment kodu za każdym razem, gdy wystąpi zdarzenie.

Przykład:

  1. Aplikacja konsolowa - kod może być wykonywany tylko w momencie uruchomienia programu. (Napisane wewnątrz głównej metody)
  2. Aplikacja Windows (interfejs użytkownika programowanie) - kod można wykonać po kliknięciu przycisku po uruchomieniu programu.

Tak mówią, nie wiesz, która metoda wywoła się w czasie kompilacji. wiesz to tylko w czasie wykonywania, czyli po kliknięciu przycisku.

Bez delegatów nie jest możliwe programowanie interfejsu użytkownika. Ponieważ wykonujesz kod za każdym razem, gdy użytkownik tworzy zdarzenia, które klikają przycisk, wpisują w polu tekstowym, wybierają pozycję dropdownlist i tak dalej....

 1
Author: shathar khan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-14 19:47:49

Delegat to coś, do czego delegowane jest zadanie. Głównym celem delegacji jest oddzielenie kodu i umożliwienie większej elastyczności i ponownego wykorzystania.

W programowaniu, a w szczególności w programowaniu obiektowym, oznacza to, że gdy metoda jest wywoływana do wykonania jakiejś pracy, przekazuje ją do metody innego obiektu, do którego ma odniesienie. Odniesienie może wskazywać na dowolny obiekt, o ile obiekt jest zgodny z predefiniowanym zestawem metod. Nazywamy to "programowaniem do interfejsu" (w przeciwieństwie do programowania do konkretnej implementacji klasy). Interfejs jest w zasadzie ogólnym szablonem i nie ma implementacji; oznacza po prostu przepis, zestaw metod, warunki wstępne i warunki postkondensacyjne (reguły).

Prosty przykład:

SomeInterface
{
   public void doSomething();
}


SomeImplementation implements SomeInterface
{
   public void doSomething()
   {
      System.err.println("Was it good for you?");
   }

}


SomeCaller
{
   public void doIt(SomeInterface someInterface)
   {
      someInterface.doSomething();
   }
}

Teraz widzisz, że mogę używać dowolnej implementacji w dowolnym momencie bez zmiany kodu w SomeCaller, ponieważ typ, który doIt() jest przekazywany nie jest konkretny, ale raczej abstrakcyjny, ponieważ jest interfejs. W świecie Javy jest to często wyrażane w paradygmacie usług, w którym wzywasz usługę (obiekt reklamujący się jako usługa za pośrednictwem określonego interfejsu), a następnie usługa wzywa delegatów, aby pomogli jej wykonać swoją pracę. Metody usługi są nazwane jako zadania gruboziarniste (makePayment (), createNewUser (), itd.), podczas gdy wewnętrznie robi wiele, jeśli nitty-gritty działa poprzez delegację, z typami delegatów są interfejsy zamiast konkretnych wdrożenia.

SomeService
{
    SomeInterface someImplementation = ... // assign here
    SomeOtherInterface someOtherImplementation = ... // okay, let's add a second

    public void doSomeWork()
    {
         someImplementation.doSomething();
         someOtherImplementation.doSomethingElse();
    }
}

(Uwaga: sposób przypisania implementacji wykracza poza zakres tego wątku. Lookup inwersja sterowania i iniekcji zależności.)

 0
Author: Aquarelle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-08 07:17:36

Chociaż nie jest to tak naprawdę "wskaźnik funkcji", delegat może wyglądać tak, jakby był to dynamiczny język, taki jak PHP:



$func = 'foo';
$func();

function foo() {
    print 'foo';
}

Lub w JavaScript możesz zrobić coś takiego:


var func = function(){ alert('foo!'); }
func();

 -1
Author: mmattax,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-11 19:43:00