-->

Help understanding .NET delegates, events, and eve

2020-02-19 13:08发布

问题:

In the last couple of days I asked a couple of questions about delegates HERE and HERE. I confess...I don't really understand delegates. And I REALLY REALLY REALLY want to understand and master them. (I can define them--type safe function pointers--but since I have little experience with C type languages it is not really helpful.)

Can anyone recommend some online resource(s) that will explain delegates in a way that presumes nothing?

This is one of those moments where I suspect that VB actually handicaps me because it does some wiring for me behind the scenes.

The ideal resource would just explain what delegates are, without reference to anything else like (events and eventhandlers), would show me how all everything is wired up, explain (as I just learned) that delegates are types and what makes them unique as a type (perhaps using a little ildasm magic)). That foundation would then expand to explain how delegates are related to events and eventhandlers which would need a pretty good explanation in there own right. Finally this resource could tie it all together using real examples and explain what wiring DOES happen automatically by the compiler, how to use them, etc. And, oh yeah, when you should and should not use delegates, in other words, downsides and alternatives to using delegates.

What say ye? Can any of you point me to resource(s) that can help me begin my journey to mastery?

EDIT One last thing. The ideal resource will explain how you can and cannot use delegates in an interface declaration. That is something that really tripped me up.

Thanks for your help.

Seth

回答1:

I would start with these:

http://www.yoda.arachsys.com/csharp/events.html

http://msdn.microsoft.com/en-us/library/ms173171.aspx



回答2:

The simplest explanation is that a delegates allow you to dynamically assign the "name" of a method to a variable or pass it around as a parameter ( you aren't assigning a string name, it is a reference to the method itself you are assigning to the variable).

Other code can then look in the variable, and invoke the method stored there later.

The delegate has to have a definition (like an interface), and for this you use the delegate keyword. Say we have a delegate definition somewhere that looks like this:

public delegate bool NotifyFriendsDelegate(int intensity);

This basically just says that any method (anywhere) that returns a boolean, and takes a single parameter of type int is an instance of this delegate. So the delegate definition specifies a shape, or signature, that methods have to match.

Then say we have a class like this:

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;
   }
}

This class represents a fictional car, and it has a simple method that causes the car to drive to our friend's house. If the car gets to our friends house, then we will want to notify our friends that we arrived... but the car class doesn't know exactly how to notify our friends. We might play the stereo really loud, we might blow the horn, or we might use a bullhorn.

Since the GoVisitMyFriends method doesn't know how to notify our friends exactly, instead it requires that the calling code pass in a reference to some method that can do the notification part. GoVisitMyFriends doesn't care which method you give it, as long as the method is shaped just like the definition of NotifyFriendsDelegate (it has to return boolean and accept one parameter of type int).

Now lets create a simple class that uses our fictional car:

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;
    }
} 

This class contains a method that conforms to the signature of the NotifyFriendsDelegate. It contains a method called DoSomethingFun, which creates an instance of MyCar then invokes the GoVisitMyFriends method. And it passes in the NotifyFriendsByRammingTheirHouse method so that the MyCar class will know how we want to show our love for our friends when we get there.

And that's the simplest form of delegate usage I can think of.

BTW: I've always found it useful to think of events as special variables that contain a collection of delegate methods. The event can be assigned any number (zero to infinity) of delegates, ALL of which will be called when the event is invoked. Events are just groups of delegates that can be treated as "one thing".



回答3:

My favorite explanation comes from Chris Sells:

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



回答4:

Take a look at the C# programming guide - here is the delegates section.