为事件处理程序使用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);
我发现了一些类似的问题来解决性能方面的问题,并指出你不能删除它们,但是我还没有发现任何解决这个简单问题的好方法吗?
是否以这种方式使用lambda表达式,或者让更多的程序员忽视这一点? 它是否隐藏难以找到的地方的事件处理程序,还是通过减少简单事件处理程序的数量来实现代码服务?
这是一个完全合理的想法 - 但在这种特殊情况下,我会使用匿名方法:
txtLogin.LostFocus += delegate
{
txtLogin.Text = "Login...";
txtLogin.ForeColor = SystemColors.InactiveCaptionText;
};
好处是你不必指定参数 - 这使得你不使用它们更清晰。 这是匿名方法对lambda表达式的唯一优势。
性能打击几乎总是可以忽略不计。 如果您确实需要移除处理程序,但无法将其移除是一个非常实际的问题,但我发现通常情况下我不这样做。 (Reactive Extensions有一个很好的方法 - 当你订阅一个可观察的序列时,你会得到一个IDisposable
,如果你打电话给它,它将删除订阅。非常整洁。)
实际上,它认为它将事件处理程序放置在易于查找的位置,即紧挨着分配给它的事件的名称。
很多时候,你会看到如下的事件处理程序:
void Text1_KeyDown(....) {....}
附加到txtFirstName的KeyUp事件,因为在使用Intellisense创建处理程序之后,某人决定重命名文本框,并且该KeyUp效果更好。 利用Lambda,对象,事件和函数都在一起。
这是一个棘手的问题。 我记得在Code Complete中读到一些(聪明的)人说你应该尽可能简单地控制流程,许多人争论一种方法的单一入口和出口点,因为不这样做会使程序难以遵循。
兰姆达斯正在变得更加远离,使得在某些情况下很难跟随发生的事情,并且控制在不同地点之间跳跃。
基本上,我认为这可能是一个坏主意,但它也很强大,使生活更轻松。 我当然使用它们相当数量。 总之,谨慎使用!
链接地址: http://www.djcxy.com/p/51441.html上一篇: Best practices of using lambda expressions for event handlers