Справка понимая делегатов.NET, события и eventhandlers [дубликат]

12
задан Community 23 May 2017 в 11:46
поделиться

4 ответа

Самое простое объяснение состоит в том, что делегаты позволяют вам динамически присваивать «имя» метода переменной или передавать его как параметр (вы не 'не присваивает строковое имя, это ссылка на сам метод, который вы назначаете переменной).

Другой код может затем заглянуть в переменную и вызвать метод, сохраненный в ней позже.

Делегат должен иметь определение (например, интерфейс), и для этого вы используете ключевое слово делегата. Скажем, у нас есть где-то определение делегата, которое выглядит следующим образом:

public delegate bool NotifyFriendsDelegate(int intensity);

В основном это просто говорит о том, что любой метод (где угодно), который возвращает логическое значение и принимает единственный параметр типа int, является экземпляром этого делегата.Таким образом, определение делегата указывает форму или подпись, которой должны соответствовать методы.

Затем предположим, что у нас есть такой класс:

public class MyCar
{

   public bool GoVisitMyFriends(NotifyFriendsDelegate thingToDoWhenWeGetThere)
   {
         var doOurFriendsLikeUs = false;
         var driving = new DrivingClass();
         var didWeGetThere = driving.DoTheDrivingNowPlease();

         if(didWeGetThere)
         {
              doOurFriendsLikeUs = thingToDoWhenWeGetThere(11);
         } 
         return doOurFriendsLikeUs;
   }
}

Этот класс представляет вымышленную машину, и у него есть простой метод, который заставляет машину подъезжать к дому нашего друга. Если машина подъедет к дому наших друзей, мы захотим уведомить наших друзей о том, что мы приехали ... но класс автомобиля не знает, как именно уведомить наших друзей. Мы могли бы включить стерео очень громко, мы могли бы дуть в рог, или мы могли бы использовать мегафон.

Поскольку метод GoVisitMyFriends не знает, как точно уведомить наших друзей, вместо этого он требует, чтобы вызывающий код передавал ссылку на какой-то метод, который может выполнять часть уведомления. GoVisitMyFriends не заботится о том, какой метод вы ему даете, если этот метод имеет форму определения NotifyFriendsDelegate (он должен возвращать логическое значение и принимать один параметр типа int).

Теперь давайте создадим простой класс, который использует нашу вымышленную машину:

public class MyFunClass()
{
    public bool NotifyFriendsByRammingTheirHouse(int howHard)
    {
         var rammingModule = new RammingModule();
         return rammingModule.RamFriendsHouse(howHard); 
    }

    public bool DoSomethingFun()
    {
         var car = new MyCar();
         var areWeCool = car.GoVisitMyFriends(NotifyFriendsByRammingTheirHouse);
         return areWeCool;
    }
} 

Этот класс содержит метод, который соответствует сигнатуре NotifyFriendsDelegate. Он содержит метод под названием DoSomethingFun, который создает экземпляр MyCar, а затем вызывает метод GoVisitMyFriends. И он передается в методе NotifyFriendsByRammingTheirHouse, чтобы класс MyCar знал, как мы хотим показать свою любовь к нашим друзьям, когда мы туда доберемся.

И это самая простая форма использования делегата, которую я могу придумать.

Кстати: мне всегда было полезно думать о событиях как о специальных переменных, которые содержат набор методов делегата.Событию может быть назначено любое количество (от нуля до бесконечности) делегатов, ВСЕ из которых будут вызываться при вызове события. События - это просто группы делегатов, которые можно рассматривать как «одно целое».

14
ответ дан 2 December 2019 в 05:53
поделиться

Мое любимое объяснение принадлежит Крису Селлсу:

http://sellsbrothers.com/public/writing/delegates.htm

6
ответ дан 2 December 2019 в 05:53
поделиться

Посмотрите руководство по программированию на C# - здесь раздел делегатов.

0
ответ дан 2 December 2019 в 05:53
поделиться