2010-07-14 38 views
11

發現lambda表達式後,他們爲匿名函數使用的實踐,我發現自己寫了很多瑣碎的事件,如這些:建議使用lambda表達式事件處理程序

txtLogin.GotFocus += (o, e) => 
{ 
    txtLogin.Text = string.Empty; 
    txtLogin.ForeColor = SystemColors.ControlText; 
}; 
txtLogin.LostFocus += (o, e) => 
{ 
    txtLogin.Text = "Login..."; 
    txtLogin.ForeColor = SystemColors.InactiveCaptionText; 
}; 

我已經也是從事件處理程序剛剛調用等功能搬走,小lambda表達式其做同樣的替換它們:

backgroundWorker.DoWork += (o, e) => DatabaseLookup.Open(e.Argument as string); 

,我發現了一些類似的問題解決performance concerns並指出你can't remove them,但我沒有發現任何解決這個簡單的問題是個好主意嗎?

是否以這種方式使用lambda表達式被認爲是很好的形式,或者做更多的經驗程序員看不起?它是否隱藏難以找到的地方的事件處理程序,還是通過減少簡單事件處理程序的數量來實現代碼服務?

回答

15

這是一個非常合理的想法 - 但在這種特殊情況下,我會使用,而不是一個匿名方法:

txtLogin.LostFocus += delegate 
{ 
    txtLogin.Text = "Login..."; 
    txtLogin.ForeColor = SystemColors.InactiveCaptionText; 
}; 

的好處是,你不必指定參數 - 這使得它更清晰的是你沒有使用它們。這是只有優勢,匿名方法已超過lambda表達式。

性能命中幾乎總是可以忽略不計。以後無法將它們刪除是一個非常現實的問題,如果你需要能夠刪除處理程序,但我發現,我經常沒有。 (Reactive Extensions有一個很好的方法 - 當你訂閱一個可觀察的序列時,你會得到一個IDisposable,如果你打電話它會刪除訂閱。非常整潔。)

1

其實,它認爲它把事件處理程序在易於查找的地方,即緊挨着分配給它的事件的名稱。

很多的時候,你會看到事件處理程序,如:

void Text1_KeyDown(....) {....} 
連接到txtFirstName的KeyUp事件

,因爲使用智能感知創建處理程序後,有人決定重新命名的文本框,並KeyUp工作得更好。利用Lambda,對象,事件和函數都在一起。

0

這是一個棘手的問題。我記得在Code Complete中讀過關於一些(聰明的)人如何讓控制流程儘可能簡單,許多人爭論一種方法的單一進入和退出點,因爲不這樣做會使程序難以遵循。

Lambdas正在離這更遠,使得在某些情況下很難跟蹤發生的事情,並且控制在不同地點之間跳躍。

基本上,我認爲這可能是一個壞主意,因爲這個,但它也是強大的,使生活更輕鬆。我當然使用它們相當數量。總之,謹慎使用!

+6

將自己限制在一個出口點是IMO可讀性災難的祕訣。如果我知道一行之後的方法的結果(例如,因爲這是一種特殊情況),那麼沒有理由讓讀者通過其餘的方法來到出口點。 – 2010-07-14 16:52:23

+0

我同意,我總是傾向於提前退出。但我知道有些人反對這一點。 – 2010-07-15 07:59:08

+0

我的理念是避免在有副作用的第一個語句和最後一個這樣的語句之間退出函數,除了從'try'塊中返回一個值可能比在阻止並從外部返回。 – supercat 2012-06-27 16:12:14