views:

27

answers:

2

When designing a derived class, are there [dis]advantages to adding a handler to a base class event in the ctor vs overriding the OnEventName() method and adding some behaviour (as well as calling the base method), if one doesn't need to change the base method and doesn't care in what order things happen, but only wants a reusable component with a little extra behaviour?

base class:

public abstract class BaseClass
{
    public event EventHandler SomeEvent;
    protected void OnSomeEvent(object sender, EventArgs e)
    {
        // do some stuff
    }
}

option A:

public class DerivedA
{
    protected override void OnSomeEvent(object sender, EventArgs e)
    {
        // do some other stuff
        base.OnSomeEvent(sender, e);
    }
}

option B:

public class DerivedB
{
    public DerivedB()
    {
        SomeEvent += (o,e) => { // do some other stuff };
    }
}
+2  A: 

There aren't any significant advantages/disadvantages to either approach.

There's a few differences between subscribing to an event vs. overriding a base-class method. For example, if you want some code to run before or after all other handlers, you should really override the OnSomeEvent method, as there's no way to gaurantee that otherwise. But you indicate you don't really care about this.

In general, overriding a method is something that requires a good understanding of the behavior of the base class to ensure that you don't inadvertantly break anything. Subscribing to an event is a less intrusive extensions, and is something that (presumably) the base class designer has planned for.

Sometimes, people argue that performance is better when overriding - but I don't buy this argument. Performance only matters when it matters. The difference here is likely so negligible, that one should be more concerned with simplicity, correctness, and easy of maintenance over performance.

LBushkin
+1  A: 

You've already mentioned the order in which things are called. Some other things which admittedly don't happen all that often, but might be significant (based on the fact that the base class controls how the event handlers are invoked):

  • Event handlers might be called on a different thread;
  • Under some circumstances, the base class might choose not to call event handlers at all;
  • The base class might catch specific types of exceptions thrown by handlers; exceptions thrown by your handler might be unintentionally swallowed.

In general, I tend to see events as being there exclusively for a class's users, with a well-designed class having virtual On... methods for subclasses.

shambulator