C# 匿名函数委托利润

C# 匿名函数委托利润,c#,events,lambda,anonymous-function,C#,Events,Lambda,Anonymous Function,我有一个按钮事件声明如下: myButton.Click += new EventHandler(ButtonClicked); private void ButtonClicked(Object s, EventArgs e) { this.Close(); } myButton.Click += (s, e) => this.Close(); 我也可以这样做: myButton.Click += new EventHandler(ButtonClicked); privat

我有一个按钮事件声明如下:

myButton.Click += new EventHandler(ButtonClicked);

private void ButtonClicked(Object s, EventArgs e)
{
  this.Close();
}
myButton.Click += (s, e) => this.Close();
我也可以这样做:

myButton.Click += new EventHandler(ButtonClicked);

private void ButtonClicked(Object s, EventArgs e)
{
  this.Close();
}
myButton.Click += (s, e) => this.Close();
我确信使用第二种方法的好处不仅仅是美观


为什么以及什么时候我应该使用第二种方法,因为我现在很困惑?如果只是为了它的外观,那么当匿名函数体中有多条指令时,它看起来就不那么干净了。

编译器为这个匿名函数生成一个方法
(s,e)=>this.Close()无论哪种方式


由您决定在何处使用它,在方法中声明它将允许您访问在该方法中声明的变量。

第一种方法更易于支持、更复杂和重用


另外,如何从事件中取消订阅第二种方法也不明显,实际上,您已将委托隐式地应用于
单击
事件

您无法在代码中的任何其他地方访问此事件。这样做的主要优点是,您不能在类中的任何其他位置调用您的方法,因为您使用的方法是邀请其他“团队成员”在其代码中访问该方法,或者可能会将其修饰符更改为他们认为应该发生的事

如果您希望能够覆盖方法,那么内联匿名赋值显然是一个不利因素


用法多少取决于您希望如何处理对逻辑的访问。

这里有一个类似的主题:考虑匿名委托和lambda表达式。特别是,答案是:一旦编译完成,它们之间就没有区别。

如果不需要参数,您可以做得更加优雅:

myButton.Click += delegate { this.Close(); };
但它的背后除了优雅的外表之外没有任何好处


如果我真的不需要lambda表达式(=>),我宁愿不使用它们,因为在调试期间您无法更改作用域代码。

只要您不需要参数,您甚至可以使用:

myButton.Click += delegate { this.Close(); };
看起来更干净

但是,正如其他人指出的那样,使用匿名委托会带来代码可重用性的成本。也在文章中。微软表示:

重要的是要注意,您不能轻易地取消订阅 事件,如果您使用匿名函数订阅它。到 取消订阅在这种情况下,有必要返回代码 在订阅事件的位置,将匿名方法存储在 委托变量,然后将委托添加到事件中。一般来说 如果您以后必须取消订阅活动,我们建议您不要使用匿名函数订阅活动 代码中的点

的一个优点(也将其与lambda表达式区分开来)是:

。。。有一种情况下,匿名方法提供 在lambda表达式中找不到功能匿名方法 允许您忽略参数列表。这意味着匿名者 方法可以转换为具有各种签名的代理。 这在lambda表达式中是不可能的

作为以上段落的结论,我们可以说,您可以不传递任何参数,或者应该传递事件处理程序的确切签名:

myButton.Click += delegate(object sender, EventArgs e) { this.Close(); };

匿名函数可以是匿名方法或lambda表达式。lamba表达式的形式如下:

()=>//dowork

匿名方法更加冗长,并且主要支持向后兼容性。匿名函数本身没有值或类型,但可以转换为委托树或表达式树。匿名函数允许我们创建在设置事件处理程序等情况下有用的内嵌方法。这一系列方法允许开发人员“在同一个地方”编写代码。换句话说,处理程序在处理事件的位置立即可供读取器使用


当实现仅限于几个语句且不可重复使用时(在事件处理程序中经常出现这种情况),我努力使用内嵌方法。Lamba表达式还可以广泛用于框架的扩展方法
可枚举。在使用新的parallels库或调用
控件时,选择
Where
等,并替换
操作
Func

技术上没有区别。在第二种情况下,编译器将生成handler方法

但坦率地说,我几乎从不使用匿名事件处理程序。为什么?因为他们没有名字。IDE无法帮助我找到处理事件的位置。您还记得您使用匿名方法订阅的确切位置吗?嗯,你可能还记得那个地方。但我打赌你的队友不会

另外,我不喜欢混合事件处理程序的样式。Visual Studio为我生成
按钮1\u单击
方法。我不喜欢某些处理程序以这种方式订阅,而有些则就地订阅


我喜欢看事件参数类型。是的,退订有时也很重要。还有几点——匿名方法对于非常简单的逻辑(比如案例中的结束形式)非常有用,但是它们会变得非常复杂。我认为,将事件处理程序放置到位打破了方法的单一责任。它订阅事件,执行其他一些操作,并在同一位置处理事件。我喜欢将事物分开,以使它们更具可读性和可维护性。

这是一个场景,例如,当创建不需要大型方法体或可重用方法的工作线程时,您希望在类中的其他地方使用它。输入和内联的速度稍微快一点(也可以考虑LINQ)。相关:@ PHAPTHANKK考虑几个按钮共享同一个点击句柄,不同的按钮可以有一个处理程序。此外,该方法可以是vitrual,也可以在inherite中重写