views:

75

answers:

3

I have seen some people leaning on handing methods to callbacks/events and then sometimes just handing them lambdas.

Can anybody speak to any difference between the two? I would have originally thought them to be the same, but the inconsistency I have seen implemented sometimes makes me wonder if there is a case where one is preferable over the other? Obviously if there is a very large ammount of code it shouldn't be an on the spot lambda, but otherwise..

Can you all outline any differences between the two if any, and outline the rules you use in choosing between the two when both are available?

+4  A: 

One of the biggest differences between the two is the ease by which you can unsubscribe from the event. With the method based approach unsubscribing is a simple operation, simply use the original method

m_button.Click += OnButtonClick; 
...
m_button.Click -= OnButtonClick;

With lambdas this is not as simple. You must store away the lambda expression and to be used later on to unsbuscribe from the event

m_button.Click += delegate { Console.Write("here"); }
...
// Fail
m_button.Click -= delegate { Console.Write("here"); } 

EventHandler del = delegate { Console.Write("here"); }
m_button.Click += del;
...
m_button.Click -= del;

It really detracts from the convenience of using lambda expressions.

JaredPar
I've gotten in a habit of += (sender, e) => { } and never thought about it but I couldn't remove that specific listener if I wanted, good point..
Jimmy Hoffa
@Jimmy, often times you don't need to and this point becomes irrelevant. But it's annoying on the times you do.
JaredPar
+1  A: 

In most languages that have lambdas (including C#), creating a lambda inside a method creates a closure -- that is, the local variables inside the declaring method will be visible to the lambda. That's the biggest difference i'm aware of.

Aside from that, unless you name your event handler somehow, in a way that's accessible in another function, you'll find it hard to detach the event handler later. This is doable by storing the delegate in an instance- or class-level variable, but it can be kinda ugly.

cHao
+1  A: 

The biggest reason for using a Lambda is to have delayed execution, i.e. you define the operations you want to perform, but you won't have the parameters until later. You generally don't use lambdas for events and callbacks; you use anonymous methods.

Using anonymous methods for events and callbacks is okay for simple events that you don't need to unsubscribe to. The biggest determining factor for me is where I'm declaring it. I'm not going to declare an event handler for a form as an anonymous method, but if I have a short-lived need to connect to an event, it might be okay.

In general, I use actual methods for callbacks and events more than anonymous methods; the events I'm handling are tied to the lifetime of the object, not the lifetime of the method, and I find that it's clearer in code to have callbacks clearly defined external to the function that hooks them up. Some of that is personal preference.

James B
Lambdas are not delay executed in the normal sense of the word. They are just delegates and have normal delegate behavior. Delayed Execution is typically used to describe LINQ queries which have different semantics than lambdas.
JaredPar
You're right, good point. LINQ is where I primarily use Lambdas, the distinction got blurred in my head there
James B