方法订阅与 lambda 委托订阅 - 哪个以及为什么?
我看到有些人倾向于将方法传递给回调/事件,然后有时只传递 lambda。
有人能谈谈两者之间的区别吗?我原本以为它们是相同的,但我所看到的实现的不一致有时让我想知道是否存在一种情况比另一种更可取?显然,如果有大量的代码,它不应该是现场 lambda,但除此之外......
你们都可以概述两者之间的任何差异(如果有的话),并概述当两者都存在时在两者之间进行选择时使用的规则有空吗?
I have seen some people leaning on handing methods to callbacks/events and then sometimes just handing them lambdas.
Can anybody speak to any difference between the two? I would have originally thought them to be the same, but the inconsistency I have seen implemented sometimes makes me wonder if there is a case where one is preferable over the other? Obviously if there is a very large ammount of code it shouldn't be an on the spot lambda, but otherwise..
Can you all outline any differences between the two if any, and outline the rules you use in choosing between the two when both are available?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
两者之间最大的区别之一是您可以轻松地取消订阅活动。使用基于方法的方法取消订阅是一个简单的操作,只需使用原始方法
使用 lambdas,这就不那么简单了。您必须存储 lambda 表达式,以便稍后使用以取消订阅事件。
这确实降低了使用 lambda 表达式的便利性。
One of the biggest differences between the two is the ease by which you can unsubscribe from the event. With the method based approach unsubscribing is a simple operation, simply use the original method
With lambdas this is not as simple. You must store away the lambda expression and to be used later on to unsbuscribe from the event
It really detracts from the convenience of using lambda expressions.
在大多数具有 lambda 的语言(包括 C#)中,在方法内创建 lambda 会创建一个闭包——也就是说,声明方法内的局部变量将对 lambda 可见。这是我所知道的最大的区别。
除此之外,除非您以某种方式以可在另一个函数中访问的方式命名事件处理程序,否则您会发现稍后很难分离事件处理程序。这可以通过将委托存储在实例级或类级变量中来实现,但它可能有点难看。
In most languages that have lambdas (including C#), creating a lambda inside a method creates a closure -- that is, the local variables inside the declaring method will be visible to the lambda. That's the biggest difference i'm aware of.
Aside from that, unless you name your event handler somehow, in a way that's accessible in another function, you'll find it hard to detach the event handler later. This is doable by storing the delegate in an instance- or class-level variable, but it can be kinda ugly.
使用 Lambda 的最大原因是延迟执行,即您定义了要执行的操作,但要稍后才能获得参数。通常,您不会将 lambda 表达式用于事件和回调;您使用匿名方法。
对于不需要取消订阅的简单事件,使用事件和回调的匿名方法是可以的。对我来说最大的决定因素是我在哪里声明它。我不会将表单的事件处理程序声明为匿名方法,但如果我有一个短暂的需要连接到事件,那么可能没问题。
一般来说,我对回调和事件使用实际方法多于匿名方法;我正在处理的事件与对象的生命周期相关,而不是与方法的生命周期相关,并且我发现在连接它们的函数外部明确定义回调在代码中更清晰。其中一些是个人喜好。
The biggest reason for using a Lambda is to have delayed execution, i.e. you define the operations you want to perform, but you won't have the parameters until later. You generally don't use lambdas for events and callbacks; you use anonymous methods.
Using anonymous methods for events and callbacks is okay for simple events that you don't need to unsubscribe to. The biggest determining factor for me is where I'm declaring it. I'm not going to declare an event handler for a form as an anonymous method, but if I have a short-lived need to connect to an event, it might be okay.
In general, I use actual methods for callbacks and events more than anonymous methods; the events I'm handling are tied to the lifetime of the object, not the lifetime of the method, and I find that it's clearer in code to have callbacks clearly defined external to the function that hooks them up. Some of that is personal preference.
在大多数情况下,实际差异很小。使用哪一个主要取决于个人喜好(即您希望代码看起来像什么)。在某些情况下,有一些实际原因选择其中一种:
有时可能会出现一种特殊情况,即选择是单独使用命名方法,还是使用然后调用该命名方法的匿名方法。需要注意的是,在没有选择其中一种的其他实际原因的情况下,在这种特殊情况下使用命名方法的效率稍高,因为它从调用中删除了一个方法调用。在实践中,您可能永远不会注意到这种差异,但这只是开销,因此如果没有具体的、实际的原因来引发它,人们可能应该避免它,即直接订阅命名方法。
In most cases, there is little practical difference. Which one to use is mainly a matter of personal preference (i.e. what you want the code to look like). In some cases, there are some practical reasons to prefer one over the other:
There is one special case that may sometimes come up, which is the choice of whether to use a named method by itself, or to use an anonymous method that then calls that named method. It is important to note that, in absence of other practical reasons for choosing one over the other, using a named method is marginally more efficient in this particular case, because it removes one method call from the invocation. In practice, you'll probably never notice the difference, but it's just overhead so if there's no specific, practical reason to incur it, one should probably avoid it, i.e. subscribe the named method directly.