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"));
//Adding an extra statement will result in a compile-time error