我看到有些人倾向于将方法交给回调/事件,然后有时只是把他们交给lambdas。
任何人都能说出两者之间的差异吗?我原本以为它们是相同的,但是我所看到的不一致有时让我想知道是否有一个比另一个更好的情况?显然,如果有大量的代码,它不应该是现场lambda,否则......
你们是否可以概述两者之间的差异(如果有的话),并概述两者在两者可用时选择的规则?
答案 0 :(得分:7)
两者之间最大的区别之一是您可以轻松取消订阅活动。使用基于方法的方法取消订阅是一个简单的操作,只需使用原始方法
m_button.Click += OnButtonClick;
...
m_button.Click -= OnButtonClick;
使用lambdas并不是那么简单。您必须存储lambda表达式,并在以后用于取消事件
m_button.Click += delegate { Console.Write("here"); }
...
// Fail
m_button.Click -= delegate { Console.Write("here"); }
EventHandler del = delegate { Console.Write("here"); }
m_button.Click += del;
...
m_button.Click -= del;
这实际上减损了使用lambda表达式的便利性。
答案 1 :(得分:2)
在大多数拥有lambda(包括C#)的语言中,在方法中创建lambda会创建一个闭包 - 也就是说,声明方法中的局部变量对lambda是可见的。这是我所知道的最大区别。
除此之外,除非您以某种方式命名您的事件处理程序,以另一种函数可访问的方式,您将发现以后很难分离事件处理程序。这可以通过将委托存储在实例级或类级变量中来实现,但它可能有点难看。
答案 2 :(得分:1)
使用Lambda的最大原因是延迟执行,即您定义了要执行的操作,但直到稍后才会有参数。您通常不会将lambdas用于事件和回调;你使用匿名方法。
对于您不需要取消订阅的简单事件,对事件和回调使用匿名方法是可以的。对我来说,最重要的决定因素是我宣称它。我不打算将表单的事件处理程序声明为匿名方法,但如果我有一个短暂的需要连接到事件,它可能没问题。
一般来说,我使用实际的方法来回调和事件而不是匿名方法;我正在处理的事件与对象的生命周期有关,而不是与方法的生命周期有关,我发现在代码中更清楚地将回调明确定义在钩住它们的函数外部。其中一些是个人偏好。
答案 3 :(得分:0)
在大多数情况下,几乎没有实际差异。使用哪一个主要是个人偏好(即您希望代码看起来像)。在某些情况下,有一些实际的理由偏爱一个:
有时会出现一种特殊情况,即可以选择是单独使用命名方法,还是使用匿名方法然后调用该命名方法。重要的是要注意,在没有其他实际原因选择其中一个的情况下,使用命名方法在此特定情况下稍微更有效,因为它从调用中删除了一个方法调用。在实践中,你可能永远不会注意到差异,但它只是开销,所以如果没有特定的,实际的理由产生它,人们应该避免它,即直接订阅命名方法。