Lambda syntax in C# 3 makes it really convenient to create one-liner anonymous methods. They're a definite improvement over the wordier anonymous delegate syntax that C# 2 gave us. The convenience of lambdas, however, brings with it a temptation to use them in places where we don't necessarily need the functional programming semantics they provide.
For instance, I frequently find that my event handlers are (or at least start out as) simple one-liners that set a state value, or call another function, or set a property on another object, etc. For these, should I clutter my class with yet another simple function, or should I just stuff a lambda into the event in my constructor?
There are some obvious disadvantages to lambdas in this scenario:
- I can't call my event handler directly; it can only be triggered by the event. Of course, in the case of these simple event handlers, there's hardly a time I would need to call them directly.
- I can't unhook my handler from the event. On the other hand, rarely do I ever need to unhook event handlers, so this isn't much of issue, anyway.
These two things don't bother me much, for the reasons stated. And I could solve both of those problems, if they really were problems, by storing the lambda in a member delegate, but that would kind of defeat the purposes of using lambdas for their convenience and of keeping the class clean of clutter.
There are two other things, though, that I think are maybe not so obvious, but possibly more problematic.
Each lambda function forms a closure over its containing scope. This could mean that temporary objects created earlier in the constructor stay alive for much longer than they need to due to the closures maintaining references to them. Now hopefully, the compiler is smart enough to exclude objects from the closure that the lambda doesn't use, but I'm not sure. Does anybody know?
Luckily again, this isn't always an issue, as I don't often create temporary objects in my constructors. I can imagine a scenario where I did, though, and where I couldn't easily scope it outside of the lambda.
- Maintainability might suffer. Big time. If I have some event handlers defined as functions, and some defined as lambdas, I worry it might make it more difficult to track down bugs, or to just understand the class. And later, if and when my event handlers end up expanding, I'll either have to move them to class-level functions, or deal with the fact that my constructor now contains a significant amount of the code that implements the functionality of my class.
So I want to draw on the advice and experience of others, perhaps those with experience in other languages with functional programming features. Are there any established best practices for this kind of thing? Would you avoid using lambdas in event handlers or in other cases where the lambda significantly outlives its enclosing scope? If not, at what threshold would you decide to use a real function instead of a lambda? Have any of the above pitfalls significantly bitten anybody? Are there any pitfalls I haven't thought of?