简体   繁体   中英

Are .NET delegates used for events?

I'm little confused, I know that delegates are like function pointers, and they are used to pass a function as a parameter into a method.

How does that fit into the event model?

Calling:

myButton.OnClick += new .....();

Is that internally just passing the method/function as a parameter when the event occurs and all the subscribers are notified about the event?

Have a look at this

Curiosity is bliss

When you do:

myButton.OnClick += new ...();

You're adding your delegate as a subscriber to that event. When the event is raised later on, all subscribers will be called (with no guarantees about order). This is called a multicast delegate. It is kinda like a function pointer with the added bonus of allowing it to "point" to more than one function.

Note that now you don't need to explicitly create the delegate, you can just use the method name:

myButton.OnClick += MethodName;

And don't forget that you can (and should, see why ) unsubscribe from events you subscribed to prevent leakage:

myButton.OnClick -= MethodName;

The event has two operators; add and remove. When you add an event handler (as in your example), the event will get a reference to the method, and add it to its list of subscribed event handlers. When the event is raised, it will go through the list and invoke the methods in it.

Indeed, a delegate is much like a function pointer. The first difference is that a delegate is composed by 2 "pointers": a function pointer and an instance pointer. Not surprisingly, the Delegate class has these two properties:

// Gets the method represented by the delegate.
public MethodInfo Method { get; }

// Gets the class instance on which the current delegate
// invokes the instance method.
public object Target { get; }

The second difference is that .NET delegates can be multicast . It's possible to add two delegates in a single MulticastDelegate. It's also possible to remove a delegate from a multicast delegate. When invoked, a multicast delegate will invoke all its child delegates. This may drive other questions, but I would be deviating from the original question.


An event , on the other hand, is a completely different stuff. In fact, an event is a property with special accessors. Regular properties have these two accessors: get and set . Events have these two instead: add and remove .

The add accessor will combine the current delegate that is in the event with the new delegate into a multicast delegate. The remove accessor will do the opposite.

Having that in mind, it's easy to understand why C# designers picked out the += and -= operators. What I mean is that the following two lines are somewhat equivalent (if you ignore that fact that the second).

myButton.OnClick += newEventHandler;
myButton.OnClick = myButton.OnClick + newEventHandler;

The event, which in the case of a button Click is the "Click" event, is acting as the "function pointer" here. Meaning, when you add your method to it using the += syntax, you're essentially making the Click Function Pointer POINT to your function. Therefore, when the button is clicked, the Click Function Pointer calls all of the functions its pointing to. Makes sense?

An event is a property based on a delegate.

It wraps a private (and hidden) delegate member.

I agree with all thats said, I'd just like to add my two cents.

If I were to re-write the documentation I would say that delegate is a pointer and part of the language while event is part of a framework that allows you to use the instrumentation of the windows-event-and-messaging-pump. You notice this when trying to use EVENTS under ASP.NET and need to wait on an event. (for more info http://discuss.joelonsoftware.com/default.asp?joel.3.456478.15 ) My problem is that MultiCast Delegates are some version in between, so is harder to differentiate and clear cut them.

delegate is a pointer to a function MultiCastdelegate is a List of delegates aggregated under one name

event is a modifier that does a few things differently 1. Runs under the ThreadContext of the caller (see BackgroundWorker and AsyncOperationManager). 2. events can be added to interfaces (clarify OO connectivity)

a delegate 1. Runs under the context of the listener 2. cannot be added to interfaces

read http://blogs.msdn.com/b/jaybaz_ms/archive/2004/06/17/158636.aspx for more data about events and race conditions in general.

The Button has a private "multicast delegate" field and the public property-like "Click" that you use the += and -= operators with is an automatically generated way to manage the state of that private field.

When the button raises the click event internally, it is invoking that private multicast delegate, which will invoke all the delegates that it currently knows about.


This system can be confusing when first implementing your own events, because the same identifier, "EventName", refers to one thing inside your class (the private multicast delegate field) and another thing outside of your class (the public management mechanism for that field).

An 'event' is a multicast delegate. For example:

public class ObservableObject : INotifyPropertyChanging, INotifyPropertyChanged
{
    public event PropertyChangedEventHandler   PropertyChanged;
}

Implementors of INotifyPropertyChanged include public event PropertyChangedEventHandler PropertyChanged . PropertyChangedEventHandler IS a delegate declared as:

public delegate void PropertyChangedEventHandler(object sender, PropertyChangedEventArgs e);

So what is this modifier event doing? First only the containing instance can invoke it. Second clients can only add/remove handlers to/from the instance.

The compiler adds two methods add_PropertyChanged and remove_PropertyChanged The compiler marks the member private.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM