How to remove a method from an Action delegate in C#

11,449

Solution 1

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;

Solution 2

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;
Share:
11,449

Related videos on Youtube

Heisenbug
Author by

Heisenbug

Updated on June 04, 2022

Comments

  • Heisenbug
    Heisenbug almost 2 years

    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.

  • Heisenbug
    Heisenbug over 12 years
    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.
  • Lucero
    Lucero over 12 years
    What do you mean by "seems not to work"? Note that -= calls into Delegate.Remove, and this will compare delegates using Delegate.Equals, 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).
  • Heisenbug
    Heisenbug over 12 years
    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?
  • Lucero
    Lucero over 12 years
    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.
  • Heisenbug
    Heisenbug over 12 years
    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?
  • DataGreed
    DataGreed over 4 years
    Btw, is there a documentation on the -= and += operators for Action delegates? Cannot find it anywhere
  • Lucero
    Lucero over 4 years
    @DataGreed This is a language feature of C#, not a framework feature. Therefore the docs are on the language pages: docs.microsoft.com/en-us/dotnet/csharp/language-reference/… and docs.microsoft.com/en-us/dotnet/csharp/language-reference/…