将 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 是否被认为是好的形式,还是更有经验的程序员会看不起这一点?它将事件处理程序隐藏在难以找到的地方,还是通过减少琐碎事件处理程序的数量来提供服务代码?
After discovering lambda expressions, and their use as anonymous functions, I've found myself writing a lot of more trivial events such as these:
txtLogin.GotFocus += (o, e) =>
{
txtLogin.Text = string.Empty;
txtLogin.ForeColor = SystemColors.ControlText;
};
txtLogin.LostFocus += (o, e) =>
{
txtLogin.Text = "Login...";
txtLogin.ForeColor = SystemColors.InactiveCaptionText;
};
I've also moved away from event handlers which just call other functions, replacing them with small lambdas which do the same:
backgroundWorker.DoWork += (o, e) => DatabaseLookup.Open(e.Argument as string);
I've found some similar questions addressing performance concerns and pointing out that you can't remove them, but I haven't found any addressing the simple question of is this a good idea?
Is the use of lambdas in such a way considered good form, or do more experience programmers look down on this? Does it hide event handlers in hard-to-find places, or does it do the code a service by reducing the number of trivial event handlers?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这是一个完全合理的想法 - 但在这种特殊情况下,我会使用匿名方法:
好处是您不必指定参数 - 这使得您更清楚地知道您没有使用它们。这是匿名方法相对于 lambda 表达式的唯一优势。
性能影响几乎总是可以忽略不计。如果您确实需要能够删除处理程序,那么事后无法删除它们是一个非常现实的问题,但我发现我经常不需要。 (反应式扩展对此有一个很好的方法 - 当您订阅可观察序列时,您会得到一个
IDisposable
,如果您调用它,它将删除订阅。非常简洁。)It's a perfectly reasonable idea - but in this particular case, I would use an anonymous method instead:
The benefit is that you don't have to specify the parameters - which makes it clearer that you're not using them. This is the only advantage that anonymous methods have over lambda expressions.
The performance hit is almost always going to be negligible. The inability to remove them afterwards is a very real problem if you do need to be able to remove the handler, but I find that often I don't. (Reactive Extensions has a nice approach to this - when you subscribe to an observable sequence, you're given back an
IDisposable
which will remove the subscription if you call it. Very neat.)实际上,它考虑将事件处理程序放在易于查找的位置,即就在其分配给的事件名称旁边。
很多时候,您会看到类似这样的事件处理程序:
附加到 txtFirstName 的 KeyUp 事件,因为在使用 Intellisense 创建处理程序后,有人决定重命名文本框,并且 KeyUp 工作得更好。使用 Lambda,对象、事件和函数都在一起。
Actually, it's consider it putting event handlers in easy-to-find places, namely right next to the name of the event it's assigned to.
A lot of the time, you'll see event handlers like:
attached to the KeyUp event of txtFirstName, because after using Intellisense to create the handler, someone decided to rename the textbox, and that KeyUp worked better. With the Lambda, the object, the event and the function are all together.
这是一个棘手的问题。我记得在代码完整中读到一些(聪明的)人如何说你应该保持控制流程简单尽可能地,许多人争论方法中的单个入口点和出口点,因为不这样做会使程序更难以遵循。
Lambda 离这个目标越来越远,在某些情况下很难跟踪正在发生的事情,控制权会从一个地方跳到另一个地方。
基本上,我认为这可能是一个坏主意,但它也很强大并且让生活更轻松。我当然大量使用它们。综上所述,谨慎使用!
It's a tricky one. I remember reading in Code Complete about how some (smart) people say you should keep the flow of control as simple as possible, with many arguing for single entry and exit points from a method, because not doing so made the program harder to follow.
Lambdas are getting even further away from that, making it very difficult in some cases to follow what's happening, with control leaping around from place to place.
Basically, I think it probably is a bad idea because of this, but it's also powerful and makes life easier. I certainly use them a fair amount. In summary, use with caution!