2

Possible Duplicate:
C# Adding and Removing Anonymous Event Handler

suppose I have an Action delegate declared this way:

public event Action<MenuTraverser.Actions> menuAction;

I am associating a method to it this way:

menuInputController.menuAction += (MenuTraverser.Actions action) => this.traverser.OnMenuAction(action);

Now, all works fine, but in certain situation I need to remove the delegated method and I don't know how. I tried this way but doesn't work:

menuInputController.menuAction -= (MenuTraverser.Actions action) => this.traverser.OnMenuAction(action);

How can I do such a thing? I need that my method OnMenuAction will be no longer called.

Community
  • 1
  • 1
Heisenbug
  • 38,762
  • 28
  • 132
  • 190
  • Maybe http://stackoverflow.com/questions/91778/how-to-remove-all-event-handlers-from-a-control ? – Matten Dec 11 '11 at 15:52

2 Answers2

6

You need to store a reference to a generic delegate into a field so later you can unsubscribe using this cached delegate field:

// declare on a class fields level
Action<MenuTraverser.Action> cachedHandler; 

// in constructor initialize
cachedHandler = (action) => this.traverser.OnMenuAction(action);

// subscribe
menuInputController.menuAction += cachedHandler;

// unsubscribe
menuInputController.menuAction -= cachedHandler;
sll
  • 61,540
  • 22
  • 104
  • 156
4

Since your signature seems to match (assuming that you have a void return type), you shouldn't need to add an anonymous function but you can use the method group directly:

menuInputController.menuAction += this.traverser.OnMenuAction;

And in this case unsubscribing should work as well:

menuInputController.menuAction -= this.traverser.OnMenuAction;
Lucero
  • 59,176
  • 9
  • 122
  • 152
  • I would happy if this works, because using @sll 's that works I'm forced to have a chached handler for each method . Anyway it seems not to work for me. – Heisenbug Dec 11 '11 at 16:31
  • What do you mean by "seems not to work"? Note that `-=` calls into [`Delegate.Remove`](http://msdn.microsoft.com/en-us/library/system.delegate.remove.aspx), and this will compare delegates using [`Delegate.Equals`](http://msdn.microsoft.com/en-us/library/99bthb1z.aspx), which states this: "Returns true if obj and the current delegate have the same targets, methods, and invocation list" - which is the case in my example but not when you have anonymous methods (which are distinct even if they have the same code in them). – Lucero Dec 11 '11 at 16:36
  • I mean that if I use your solution then delegate won't be removed. Maybe I'm doing something wrong but simply replacing my code with your, it doesn't. And still I don't understand a thing: Was I using anonymous methods? – Heisenbug Dec 11 '11 at 16:59
  • Is `menuAction` using the default event code or does it have custom `add` and `remove` handlers? Because if it has the default handlers my code works. And yes, you were using anonymous methods: `(MenuTraverser.Actions action) => this.traverser.OnMenuAction(action)` is (for this use case - because it doesn't compile to a lamdba-expression) identical to this: `delegate(MenuTraverser.Actions action) { this.traverser.OnMenuAction(action); }` which is an anonymous method. – Lucero Dec 11 '11 at 17:03
  • Oh..you are right. Your code works (I had a bug). And thanks for the clarification on anonymous method. I was using them without without knowing it. So I was doing the right thing except for having used anonymous methods, right? – Heisenbug Dec 11 '11 at 17:10
  • Btw, is there a documentation on the `-=` and `+=` operators for Action delegates? Cannot find it anywhere – DataGreed Aug 08 '19 at 13:50
  • @DataGreed This is a language feature of C#, not a framework feature. Therefore the docs are on the language pages: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/subtraction-operator and https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/addition-operator – Lucero Aug 08 '19 at 14:19