Ho to ...

  • Thread starter Thread starter Jacek Jurkowski
  • Start date Start date
J

Jacek Jurkowski

.... Clear all delegates assigned to an Event?
F.e. lets consider the button.

Button.Click += new EventHandler(...);
Button.Click += new EventHandler(...);

How to free that event now?
 
Jacek Jurkowski said:
... Clear all delegates assigned to an Event?

From inside the class that declares the event in the default way, one
can assign null to the event:

---8<---
class Test
{
public static event EventHandler Foo;

public static void Bar()
{
Foo = null;
}
}
--->8---
F.e. lets consider the button.

Button.Click += new EventHandler(...);
Button.Click += new EventHandler(...);

From outside the class, you've only got access to the += and -=
operators, which map (internally) to add_<eventName> and
remove_<eventName>. Because you can use this syntax:

---8<---
public event EventHandler Foo
{
add { /* ... */ }
remove { /* ... */ }
}
--->8---

.... there is no way for you to enumerate or otherwise get access to the
implementation details of the storage behind an event handler. The event
handlers could be stored in a hash table or other structure.

So, if you need to clear all events, you must either:

1) Keep track of what you added so you can remove it again later.

or

2) Add a method to the class (if you have written it) which permits
clearing events.

-- Barry
 
Actually, you can enumerate the registered event handlers using
Delegate.GetInvocationList(). This I have done many times.

There are also a couple methods of the Delegate class that may be the answer
to the OP's question but I have never used them so I can't say for certain.
The RemoveAll or RemoveImpl may be able to do what he asks.

Additionally, keep in mind that when adding a new member to the invocation
list of an event, we use += specifically in order to not erase the previous
registered handlers. Therefore, if you say

Button1.Click = null;

that should clear all of the event handlers from the button click event.

HTH

Dale
 
Dale said:
Actually, you can enumerate the registered event handlers using
Delegate.GetInvocationList(). This I have done many times.

That is for *delegates*, not *events*. Try calling GetInvocationList()
on the Button class's Click event.
There are also a couple methods of the Delegate class that may be the answer
to the OP's question but I have never used them so I can't say for certain.
The RemoveAll or RemoveImpl may be able to do what he asks.

Assigning null does exactly what the OP needs, he wanted to clear all
delegates assigned to an event. RemoveAll() applied to every delegate
that was added to a delegate *will* result in null:

---8<---
using System;
using System.Reflection;

class App
{
static void Handler(object sender, EventArgs e)
{
}

static void Main(string[] args)
{
EventHandler h = Handler;
h = (EventHandler) Delegate.RemoveAll(h,
new EventHandler(Handler));
Console.WriteLine("h == null? {0}", h == null);
}
}
--->8---
Additionally, keep in mind that when adding a new member to the invocation
list of an event, we use += specifically in order to not erase the previous
registered handlers. Therefore, if you say

Button1.Click = null;

You can't do that from outside the class, as I mentioned in my previous
post.
that should clear all of the event handlers from the button click event.

It won't. Try this:

---8<---
using System.Windows.Forms;

class App
{
static void Main(string[] args)
{
new Button().Click = null;
}
}
--->8---

You'll get a compiler error:

error CS0079: The event 'System.Windows.Forms.Control.Click' can only
appear on the left hand side of += or -=

The reason is that there are only two methods associated with the event
implemnetation, add_* and remove_*, so there is no mechanism for
clearing all the events.

-- Barry
 
Back
Top