简体   繁体   中英

Events and Delegates Order when event is triggered

I recently attended a interview in C# where i was asked a question about Events and delegates in C#

The person asked me when a event say button gets clicked, which gets called first event or delegate?

Does the delegate calls the event or the event calls delegate?

Can we have a event without a delegate in c#?

The person asked me when a event say button gets clicked, which gets called first: the event or the delegate?

When you open a door, which gets opened first: the door or the doorknob ?

Huh?

That question doesn't make any sense. You open a door with a doorknob, but you don't open a doorknob .

What does it mean to "call" an event? Events aren't things that you call. Events are things that you raise . Raising an event is identical with calling the delegate.

Does the delegate calls the event or the event calls delegate?

Does the door open the doorknob, or does the doorknob open the door?

Again, the question doesn't make sense. A doorknob is not something that can be "opened", and the doorknob does not open the door -- you open the door, by holding the doorknob.

Does the delegate call the event? No; events are not things that can be "called". Does the event call the delegate? No, the code that is raising the event calls the delegate .

Can we have a event without a delegate in c#?

Yes, in the sense that the delegate reference associated with an event can be a null reference. But every event is associated with a delegate type, and somehow has associated with it a reference to a delegate.

The whole set of questions indicates to me that the questioner does not have a very good understanding of the relationship between events and delegates. A good way to think about it is that an event is just a property that contains a reference to a multicast delegate. Whereas a property has special methods that get and set the value of the property, an event has special methods that add and remove delegates to the multicast delegate.

Events are a concept which utilize delegates as a means to call methods that have subscribed to them.

Events themselves are not called. When a piece of code raises an event, it will call each of the subscribed methods by invoking the delegates.

Events are raised, delegates are called. So when the button is clicked, a buttonClick event is raised, meaning that each delegate subscribed to the event will be called, according to the subscription order.

This page bubbled up on top of Google results, so below is something you might find useful if you also land here. Multi-cast delegates ARE called (see MSDN) in deterministic order on one thread, in the order of assignment. This assignment will involve an array of some sort, and it would be illogical for the indices to fill up out of order.

public partial class Form1 : Form
{
    ob<Control>ob1;
    ob<Control>ob2;
    ob<Control>ob3;

    public Form1()
    {
        InitializeComponent();

        ob<Control>.setup(button1);
        ob1 = new ob<Control>(1, true);
        ob2 = new ob<Control>(2, false);
        ob3 = new ob<Control>(3, false);
    }

    public class ob<T> where T : Control
    {
        int ndx;
        Boolean isSentinel;
        static Boolean dontdostuff;
        static T c;
        public static void setup(T c) {ob<T>.c = c;}//an argument less from constructor, useful for many objects (more likely to be menuitems)

        public ob(int ndx, Boolean isSentinel)
        {
            this.ndx = ndx;
            this.isSentinel = isSentinel;
            c.Click += new EventHandler(click);
        }

        void click(object sender, EventArgs e) 
        { 
                    if( isSentinel)
                    {
                        if (MessageBox.Show("ob" + ndx + " asks:  short circuit subsequent delegate calls?", "", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK)
                        {
                            dontdostuff = true;
                            return;
                        }
                        else
                        {
                            dontdostuff = false;
                        }   
                    }
                    else
                    {
                        if( dontdostuff) return;
                    }
                 MessageBox.Show("ob" + ndx + " doing stuff in order of handler addition", "", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
    }

An event is simply a code construct implemented in .NET as a multi-cast delegate.

When an event is "raised" (which can only be done by code in the same class as the event; event raising must happen within "protected" scope), the delegates are invoked one at a time, in a synchronous fashion but not necessarily in any deterministic order. The event IS the delegate, so when the event is raised for a button being clicked, the delegates are invoked by the runtime, which has received the Windows message that the user clicked on the GUI area for the button.

The statements "the event is raised" and "the delegates are invoked" are equivalent statements; it's like asking "which comes first, the chicken or the gallus domesticus ?".

Now, events often cascade, especially when we're talking about UI. There is a MouseUp event, invoked when the mouse button is released, which can fire one or more other events such as MouseClick, MouseDoubleClick, DragDrop, etc. You may not attach a handler to the MouseUp event, but there is built-in logic behind the scenes of MouseUp to raise the MouseClick event which you DO handle. So, in this sense, you could say that the MouseUp event "comes first" and calls the MouseClick handler delegate.

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