Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How events are assigned in .NET

Tags:

.net

events

I just realized I don't fully understand why in .NET you assign events using a += symbol.

I figured this out yesterday when I needed to remove an event and without thinking I was doing

someobject.onsomeevent += null

thinking that would just remove the event I had previously assigned.

After some investigation, I figured out I had to

someobject.onsomeevent -= someeventmethod;

After figuring this out, I realized I don't understand how event methods are assigned in .NET.

So I have a few questions:

First, does it mean that I can do

someobject.onsomeevent += someeventmethod;
someobject.onsomeevent += someeventothermethod;

If so, when onsomeevent occurs will they both get hit, and in the order specified or simultaneously?

Furthermore, how can I determine what event methods are already assigned to someobject.onsomeevent?

Second, is there a way to save the events methods in some class, remove them from someobject.onsomeevent and re-assign them after some other procedures that would normally trigger the event are complete?

like image 924
Matt Avatar asked Jun 03 '10 19:06

Matt


4 Answers

Regarding your first question: You get multicast behaviour by default. That is, if you have multiple handlers then by default the event handlers will be called in sequence (unless one of them throws an exception). Note that you can change add (+=) and remove (-=) to do something different than the default behaviour.

Jon Skeet has a page explaining delegates and events in C# which you might want to read.

like image 71
Mark Byers Avatar answered Nov 02 '22 07:11

Mark Byers


First question: Yes you can do it, as long as the method signatures are compatible with the delegate type of the event.

Second question: Yes you can do that, too. Use EventTest.GetInvocationList() to get the methods registered to your event. And then use -= and += to remove and re-add the delegates, respectively. See the example below:

  public class Test 
  {
        public event EventHandler EventTest = delegate { };
        public void Method()
        {
            //get registered event handlers
            Delegate[] invocationList = EventTest.GetInvocationList();

            //remove them
            foreach (Delegate d in invocationList)
            {
                EventTest -= (EventHandler)d;
            }

            //this method won't trigger anything, because 
            //invocation list is empty
            Method2();

            //re-add event handlers
            foreach (Delegate d in invocationList)
            {
                EventTest += (EventHandler)d;
            }
        }

        public void Method2()
        {
            if(EvenTest != null)
            EventTest(this, EventArgs.Empty);
        } 
   }

I removed the trivial Main()-method to make the code more readable.

like image 33
Simon Avatar answered Nov 02 '22 07:11

Simon


So the answer is yes, yes and sequentially in the order added.

An event is an instance of the MulticastDelegate class. To find out what delegates are assigned to the event call the GetInvocationList method on the event. See http://msdn.microsoft.com/en-us/library/system.multicastdelegate.getinvocationlist%28v=VS.71%29.aspx

This will give you an array of delegates. So you could call GetInvocationList to get the existing event handlers; then clear the event handlers from the event; perform some action; and then reassign the handlers back to the event.

like image 32
Mark Arnott Avatar answered Nov 02 '22 09:11

Mark Arnott


Delegates are 'multicast' in .NET and events are property-like wrappers. You can get a better undestanding by looking at an event in long-form notation:

private EventHandler _handler;

public event EventHandler MyEvent
{
  add { _handler = (EventHandler)Delegate.Combine(_handler, value);  }
  remove { _handler = (EventHandler)Delegate.Remove(_handler, value); }
}

You would normally write all of the above in 1 line:

public event EventHandler MyEvent;

And to be complete, an event constains an Invocationlist that it processes sequentially when triggered. There are no guarantees about order.

like image 28
Henk Holterman Avatar answered Nov 02 '22 08:11

Henk Holterman