views:

396

answers:

4

I was reading Jon Skeet's refcard on C#. He stated:

"Events are closely related to delegates but they are not the same thing."

So from my understanding, when events are raised, handlers (delegates) execute the code.

I have the following doubts:

(1) When we declare an event , will it be registered in any "REGISTERS?" or "System Registries"?

(2) The Old VB 6.0 style handles the event without delegates ,so why can't we write a event without delegates?

How does the flow going for Win Forms: If I click a button, it will print hello (following example).

button_click( sender,some event args  )
{
    print();
} 

void print( )
{
    console.WriteLine ("Hello");
}

How is this event flow internally linked and handled? (What is internally happening in the CLR?)

(3) What is the logic behind the event that prevents the event from returning a value?

Thanks everybody, for spending your golden time.

+4  A: 

A delegate is a type definition. It specifies the signature that a method must have to be compatible.

An event is a property-like class member, based on a delegate-type. It provides encapsulation, the only public actions are to Add (+=) or Remove (-=) a handler.

(1) No, an event is not registered anywhere. But it is the place where handling methods are registered.

(2) I don't know how VB6 works but in .NET all events are based on delegates.

(2b) What's happening when the Button is clicked is that the button-code checks if the event is not null and then calls the event (like a method). The event iterates over its Invocation list and calls all registered handlers.

there is a little more to it, a ButtonClick is originated by the Button itself when it handles and processes Mouse and/or Keyboard events. Those events are coming from the MessageLoop (Application.Run). But on a CLR level, that just means the MessageLoop calls a method (Control.Perform(..)) on the Button.

(3) You can write a Delegate and/or Event that returns a Value just fine. But think about what that means when there are multiple handlers. The signature void handler(object sender, Eventargs e) is a (strong) recommendation.

Henk Holterman
A: 
  1. I don't know on this one... but my first thought is on the heap since that's where most objects live and events are part of the object.... but I am venturing a guess on this one....

  2. They actually do but behind the scenes for you. This is a feature of VB.

  3. They can have more than one delegate / listener and the order of when the listeners are fired is not guaranteed. The convention is to use an eventarg object to return information to the handler. http://stackoverflow.com/questions/924689/why-events-have-no-return-types-in-net goes into a little better description on this.

klabranche
A: 

1) No, the event handlers will simply be registered with the Event (which contains a list of handlers).

2) I'm not particularly well-versed in VB6, but I'm fairly certain that it had a similar mechanic since, in essence, a Delegate is simply a strong-typed method pointer.

In your example, the Button.Click event contains a reference to the delegate button_click( sender,some event args) which it calls upon the event being triggered. It doesn't contain any reference to print, just a reference to the method it must call.

3) As there can be multiple handlers for a single event (or none at all), having a return value can often times be illogical behavior. As such, most event handlers have void return. That being said, you can create custom events that can have any signature. The void (object sender, EventArgs e) signature is the base signature for most, if not all, Microsoft events.

CMerat
+1  A: 

Events are implemented using delegates:

This code:

public event EventHandler<YourEventArgs> YourEvent;

Will be compiled into something like this:

// a private field
private EventHandler<YourEventArgs> YourEvent = null;

// public add_ method
[MethodImpl(MethodImplOptions.Synchronized)]
public void add_YourEvent(EventHandler<YourEventArgs> value)
{
 YourEvent = (EventHandler<YourEventArgs>)
 Delegate.Combine(YourEvent, value);
}

// public remove_ method
[MethodImpl(MethodImplOptions.Synchronized)]
public void remove_YourEvent(EventHandler<YourEventArgs> value)
{
 YourEvent = (EventHandler<YourEventArgs>)
 Delegate.Remove(YourEvent, value);
}

So when you declare an event you actually declare these 2 functions. As you can see these functions incapsulate access to the delegate field. That's why you cannot assign delegate value to the event, only subscribe or unsubscribe.

This code explains why events may be declared using the following syntax:

public event MyDelegate MyEvent
{
    add
    {
        ...
    }

    remove
    {
        ...
    }
}

1) Event will not be registered into any kind of the registry. Memory for event (for private delegate field) will be allocated on the heap because delegates are reference types.

2) Events are built on top of delegates thus you cannot use them without delegates.

3) The 3rd question is already answered by Henk Holterman (+1) and other folks.

Hope this helps.

Alex