Делегаты C#

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by shadowmaster, 2 Sep 2010.

  1. shadowmaster

    shadowmaster New Member

    Joined:
    16 Aug 2010
    Messages:
    17
    Likes Received:
    0
    Reputations:
    0
    Собственно где более менее понятно написано про оные ?
    Для уровня выше среднего.
    Прочитал msdn разобрал примеры, но так не пойму их практического применения.
     
  2. .ATK

    .ATK Active Member

    Joined:
    20 Feb 2009
    Messages:
    143
    Likes Received:
    111
    Reputations:
    9
  3. Bers

    Bers Member

    Joined:
    17 May 2010
    Messages:
    78
    Likes Received:
    30
    Reputations:
    26
    Вот это самому прочесть никак? Хорошо, я прочту вслух: делегат - это суть указатель на функцию. Зачем нужен указатель на функцию? Чтобы дать возможность одной функции вызывать другую, неизвестную заранее (например, делегат на эту вызываемую функцию передается в вызывающую функцию как параметр). Теперь то же самое, но на примерах.

    Пример номер раз. События.
    События в .NET реализованы по сути как мультикаст делегат. Такой делегат ссылается не на одну функцию, а на список онных. Если у тебя есть такое событие:
    PHP:
    public class Foo
    {
      public 
    event EventHandler Bar;
    }
    То для того, чтобы подписаться на него, нужно передать в событие экземпляр делегата на функцию-обработчик:
    PHP:
    private void Foo_OnBar(object senderEventArgs e)
    {
      
    System.Console.WriteLine("Foo.Bar triggered");
    }

    .....


    var 
    foo = new Foo();
    foo.Bar += new EventHandler(Foo_OnBar);
    // еще можно написать так:
    foo.Bar += Foo_OnBar;
    // в этом случае компилятор сам добавит создание экземпляра делегата.
    Пример номер два. LINQ и ему подобные вещи.
    Взглянем на такой LINQ-запрос:
    PHP:
    var input = new [] { 123456};
    var 
    result input.Where(=> 0);
    А теперь взлянем на сигнатуру метода System.Linq.Enumerable.Where():
    PHP:
    public static IEnumerable<TSourceWhere<TSource>(this IEnumerable<TSourcesourceFunc<TSourceboolpredicate);
    Вспомним, что Func<TX, TY> есть делегат такого вида:
    PHP:
    public delegate TY Func<TXTY>(TX x);
    Т.е. предикат, передающийся в метод Where, - это тоже делегат. В данном случае это делегат на анонимный метод, к тому же его тип был выведен компилятором.
    Если переписать этот LINQ-запрос, используя синтаксис query comprehension, то делегаты станут еще более неявными :)
    PHP:
    var result from x in input
                  where x 
    0
                  select x
    ;
    Однако это тот же самый запрос, и внутри него те же самые делегаты.

    Пример номер три. Простое делегирование :)

    Приведу еще пример простого делегирования, например, пусть это будет выполнение кода в потоке из пула потоков.

    PHP:

    System
    .Threading.ThreadPool.QueueUserWorkItem=>
    {
      
    // do something
      
    System.Console.WriteLine("Job is done");
    });
    Ну, тут тоже хорошо видно, что сигнатура у метода QueueUserWorkItem примерно такая:
    PHP:
    public static void QueueUserWorkItem(WaitCallback callback);
    Где
    PHP:
    public delegate void QueueUserWorkItem(object state);
    Т.е., грубо говоря, делегаты используются почти везде. Сложно прочесть про них на MSDN и не понять, где же они вообще используются :)
     
    1 person likes this.