2010-07-14 37 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