5

I often run into a situation where I want to subscribe to an event, but I want to use a lambda to do so:

public class Observable
{
    public event EventHandler SomethingHappened;

    public void DoSomething()
    {
        // Do Something...
        OnSomethingHappened();
    }
}

// Somewhere else, I hook the event
observable.SomethingHappened += (sender, args) => Console.WriteLine("Something Happened");

The problem I run into is that I don't know how to unhook the event. Since the lambda creates an anonymous delegate under the hood, I have nothing to call -= on.

Now, I could just create a method:

private void SomethingHappened(object sender, EventArgs args)
{
    Console.WriteLine("Something Happened");
}

And then I can hook/unhook all I want:

observable.SomethingHappened += SomethingHappened;
observable.SomethingHappened -= SomethingHappened;

But I'd really, really, really like to use my lambda instead. In a more complicated example, lambdas come in really handy here.

I am pretty sure that I am out of luck... but I was wondering if anyone out there has figured out a way to do this?

Brian Genisio
  • 47,787
  • 16
  • 124
  • 167
  • Yes, try this: http://stackoverflow.com/questions/1747235/weak-event-handler-model-for-use-with-lambdas/1747236#1747236 – Benjol Nov 17 '09 at 07:56

3 Answers3

10

This question was already asked

The answer is: put your lambda in a variable.

EventHandler handler = (sender, args) => Console.WriteLine("Something Happened");
observable.SomethingHappened +=  handler;
observable.SomethingHappened -=  handler;
Community
  • 1
  • 1
Stefan Steinegger
  • 63,782
  • 15
  • 129
  • 193
  • You cannot use this, since lambda cannot be assigned to var. Instead you should use [delegate notation] (http://stackoverflow.com/questions/805829/how-to-unsubscribe-from-an-event-which-uses-a-lambda-expression/805882#805882), or use actual event type instead of var. – Ivan Aug 09 '11 at 00:34
8

Unforutantely there is not a great way to do this. You are really stuck with one of two options

  • Use a method as you described
  • Assign the lambda to a variable and use the variable to add / remove the event
JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
0

Well, if you know your code is the only one hooking up the event, assigning null to the event variables will remove all delegates (but can be very bad form if you want the code to be extensible).

Otherwise, you should just keep the lambda around in a separate variable and use that to unhook the event.

Pontus Gagge
  • 17,166
  • 1
  • 38
  • 51
  • You can't do this. Only the class that owns the event may set the event property to null. Clients to Observable may not do this. If the event were a multi-cast delegate, clients can set to null, but events are forbidden. In either case, I agree. Bad form. – Brian Genisio May 13 '09 at 19:40