C#Lambda表达式作为事件处理程序

示例

Lambda表达式可用于处理事件,在以下情况下非常有用:

  • 处理程序很短。

  • 处理程序永远不需要取消订阅。

下面给出了一个可能使用lambda事件处理程序的良好情况:

smtpClient.SendCompleted += (sender, args) => Console.WriteLine("Email sent");

如果有必要在代码的某个将来点取消订阅已注册的事件处理程序,则应将事件处理程序表达式保存到一个变量中,并通过该变量进行注册/取消注册:

EventHandler handler = (sender, args) => Console.WriteLine("Email sent");

smtpClient.SendCompleted += handler;
smtpClient.SendCompleted -= handler;

这样做的原因不是简单地逐字重新键入lambda表达式以取消订阅(-=),原因是C#编译器不一定会认为两个表达式相等:

EventHandler handlerA = (sender, args) => Console.WriteLine("Email sent");
EventHandler handlerB = (sender, args) => Console.WriteLine("Email sent");
Console.WriteLine(handlerA.Equals(handlerB)); // May return "False"

请注意,如果向lambda表达式添加了其他语句,则可能会意外省略所需的大括号,而不会引起编译时错误。例如:

smtpClient.SendCompleted += (sender, args) => Console.WriteLine("Email sent");emailSendButton.Enabled= true;

这将进行编译,但会导致将lambda表达式添加(sender, args) => Console.WriteLine("Email sent");为事件处理程序,并emailSendButton.Enabled = true;立即执行该语句。要解决此问题,lambda的内容必须用大括号括起来。可以通过从一开始使用花括号来避免这种情况,在向lambda-event-handler添加其他语句时要格外小心,或者从一开始就用圆括号将lambda括起来:

smtpClient.SendCompleted += ((sender, args) => Console.WriteLine("Email sent"));
//添加额外的语句将导致编译时错误