编写内联事件处理程序是不好的做法

Hom*_*mam 58 c# event-handling inline-code

编写内联事件处理程序是不好的做法吗?

对我来说,当我想在事件处理程序中使用局部变量时,我更喜欢使用它,如下所示:

我更喜欢这个:

// This is just a sample
private void Foo()
{
    Timer timer = new Timer() { Interval = 1000 };
    int counter = 0; // counter has just this mission
    timer.Tick += (s, e) => myTextBox.Text = (counter++).ToString();
    timer.Start();
}
Run Code Online (Sandbox Code Playgroud)

而不是这个:

int counter = 0; // No need for this out of Boo & the event handler

private void Boo()
{
    Timer timer = new Timer() { Interval = 1000 };

    timer.Tick += timer_Tick;
    timer.Start();
}

void timer_Tick(object sender, EventArgs e)
{
    myTextBox.Text = (counter++).ToString();
}
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 76

这绝对没问题 - 虽然有两点需要注意:

  • 如果要从闭包中修改局部变量,则应确保了解自己正在做什么.
  • 您将无法取消订阅该活动

通常我只内联非常简单的事件处理程序 - 对于任何更复杂的事情,我使用lambda表达式(或匿名方法)通过使用更合适的方法调用方法来订阅:

// We don't care about the arguments here; SaveDocument shouldn't need parameters
saveButton.Click += delegate { SaveDocument(); };
Run Code Online (Sandbox Code Playgroud)

  • @SmartyP:用户应该知道他们是否需要取消订阅事件——这并不真正在这个问题的范围内,IMO。我已经明确表示他们不能这样做,这意味着如果他们*需要*,他们就会知道不要使用匿名函数。 (4认同)
  • 这个答案可能会让人们走上一条糟糕的道路。事件处理程序不能取消订阅的重要性取决于应用程序。在内存受限的情况下(例如:在移动设备上),清理事件处理程序以确保 ViewControllers 和 Activities 可以被正确地垃圾收集是很重要的。如果不这样做,可能会导致显着的内存分配增加,或者当为导航返回堆栈中且当前未显示的屏幕触发事件时出现意外行为。重要的是要根据您的用例了解不取消事件是否可以。 (3认同)