C# 在事件内部编写方法体可以吗?
我最近从一位大学老师那里看到了一些代码,他有这样的代码:C# 在事件内部编写方法体可以吗?,c#,C#,我最近从一位大学老师那里看到了一些代码,他有这样的代码: public void Button1_Click(blabla) { //His code was here. } 调用一个方法来做脏活不是更好的编程实践吗?那样的话,如果方法改变了,你只需要改变方法本身,而不需要改变事件?(打破某物的可能性较小) 我个人认为这取决于代码的长度,以及代码是否在逻辑上位于那里 因此,如果它只有1或2行,那么我在内部执行,但是如果它的代码行数更多,我就用一个单独的方法执行。是的,额外的方法“更好”,
public void Button1_Click(blabla)
{
//His code was here.
}
调用一个方法来做脏活不是更好的编程实践吗?那样的话,如果方法改变了,你只需要改变方法本身,而不需要改变事件?(打破某物的可能性较小)
我个人认为这取决于代码的长度,以及代码是否在逻辑上位于那里 因此,如果它只有1或2行,那么我在内部执行,但是如果它的代码行数更多,我就用一个单独的方法执行。是的,额外的方法“更好”,但你必须将其与YAGNI(你不需要它)的反原则进行权衡 有两个原因认为额外的方法更好:
这两者都归结为封装和将行为与事件分离的思想。没有人会在以后处理这段代码时重构以删除额外的方法,但是在没有额外方法的情况下处理代码的人可能会重构以添加它。但是再一次-YAGNI.如果您不打算重用代码,那么它不会有什么不同-它只是开销。如果您打算从代码中的其他位置调用“DoSomething()”,那么请务必将其提取出来。如果需要,只需提取
DoSomething
a) 它的功能在其他地方需要,或者可能需要
b) 这是一段相当长的代码
如果事件是唯一使用它的地方,那么就不需要提取它。不,不一定
除非你也要在代码的其他地方使用DoSomething()
,否则把它分解成一个单独的方法是毫无意义的
Button1\u Click本身已经是一种方法。它恰好是一个与click事件委托匹配的生成头。你可以随意命名,一切都会按照你想要的方式进行。如果它是可重用代码,那么就把它放在外面。还有一些编码指南,检查你公司的政策,强迫你选择第二种风格
Grz,Kris.这样将它们分开是有一定意义的,如果您想从其他地方调用
DoSomething
(在其他地方提供发送方和事件参数是没有意义的),这非常有用
然而,这里有一个更好的选择——至少如果您是以编程方式订阅的话。请改用匿名方法或lambda表达式:
button.Click += delegate { DoSomething(); }
很明显,在订阅时,您没有使用其他参数,也没有浪费额外的方法
这样做的缺点是它不适用于VisualStudio的设计器生成的事件订阅。就我个人而言,我希望Visual Studio支持使用不包含所有委托参数的方法订阅事件-它可以自动生成匿名方法(或lambda表达式)。在我看来,这将是两全其美
正如其他答案所说,如果不需要从其他任何地方调用,我认为将方法体保留在事件处理程序方法中是合理的。大多数现代设计方法(例如MVC、MVVM)在事件处理程序中只有最少的代码,将所有程序逻辑传递给一个单独的(单元可测试)类
但是,对于课堂教学(或演示代码),我认为直接使用事件处理程序没有什么错。该方法的内容是什么?如果它与UI(例如更新可见/启用状态)有着非常明确的关联,并且没有从其他任何地方调用,那么您最好将其保留在处理程序中。但是,如果该方法对您的数据/逻辑层所做的事情超出了在这些层中委托函数调用的范围,那么可能值得打破一些逻辑,并可能将其移动到另一层。我唯一一次将严格与UI相关的代码分支到它自己的方法时,我必须从多个事件处理程序更新相同或类似的状态。如果Button1\u Click only调用DoSomething,那么破坏某些内容的可能性如何降低?后者的唯一进步是更容易切换事件处理程序(DoSomething可以重用)。请记住,你是在引导我们问“这不是更好吗…”@Matt:也许你想在用户单击表单上的按钮时重复同样的事情,但也有一个做同样事情的菜单项。在一个方法中包含它会让你和其他人更容易做到这一点。在这种情况下,它变成了一个代码重用的问题,而不是提取处理代码是否正确的问题。+1 Jon,一如既往的好答案。只是一个问题,我在这种情况下使用了lambda:
button.Click+=(o,a)=>{DoSomething();}
您对此有何想法?我认为编译器会以任何一种方式对其进行优化。这行得通吗?我认为它必须有两个参数。类似于button.Click+=(u,u)=>DoSomething()
也许相反?@Domenic:这是匿名方法能做的一件事,而lambda表达式不能@吉姆:真的没有太多需要优化的地方——我更喜欢这里的匿名方法,因为它确切地说明了它在做什么;lambda表达式提到了它无意使用的参数。
button.Click += delegate { DoSomething(); }