Is it bad practice to write inline event handlers

Is it bad practice to write inline event handlers ?

For me, I prefer use it when I want to use a local variable in the event handler like the following:

I prefer this:

// 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();
}

Instead of this:

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();
}

It's absolutely fine - although there are two caveats:

  • If you're modifying a local variable from within a closure, you should make sure you understand what you're doing.
  • You won't be able to unsubscribe from the event

Typically I only inline really simple event handlers - for anything more involved, I use lambda expressions (or anonymous methods) to subscribe with a call to an method with a more appropriate method:

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

In most cases I would rather have the separate methods like “timer_Tick()”, however I should rather it be called OnTimerTick() as:

  • When I read the class, it is clearer wheat is going on. The “On” tells me its can event handler.
  • It is easier to set a break point in the method in the “inline” case.
  • The event is fired a long time after “Foo” contractor has returned, and I don’t think it as running in t the scope of the contractor.

However if the event will only be fired before the method it is declared in-line returns and the object the event is set on has a scope what that is limited to the declaring method, then I think the “in line” version is better. Hence I like using “in line” for the compare delegate being passed to a “sort” method.