views:

73

answers:

4

I have this kind of code:

public class Foo
{
  public SomeHandler OnBar;

  public virtual void Bar()
  {
  }
}

Foo is a base class and therefor other classes might inherit from it.
I would like the OnBar event to always be fired when Bar() is called even if it's not called explicitly inside Bar.
How can it be done?

+2  A: 

Short answer: you can't. Not with what Microsoft gives you out of the box.

That said, take a look at "aspect oriented programming" in .NET. Google that, you might get something useful.

Added: The standard way would be to raise the event in the Bar() method and then require all derived classes to call the base implementation. But you can't enforce it.

Vilx-
+9  A: 

A common pattern is to have a non-virtual method that will do what you want that calls a virtual method. Subclasses can override the inner method to change the functionality, but the public method can be non-virtual on always raise the event first.

public class Foo
{
    public SomeHandler OnBar;

    public void Bar()
    {
        if (OnBar != null)
        {
            OnBar(this, EventArgs.Empty);
        }
        BarImpl();
    }

    protected virtual void BarImpl()
    {
    }
}
Quartermeister
Basically an implementation of the template method pattern + 1
DanP
So this is the best way? In C++ I would use bind() to create a new function out of the event calling function and the original function.
the_drow
+1  A: 

first of all the code you provided will not compile.
virtual functions must have a body.

To ensure the event is fired you can do something like this.

public class Foo
{
  public SomeHandler OnBar;

  public void Bar()
  {
     OnBar();  (check for nulls)
     ProtectedBar();
  }

  protected virtual ProtectedBar()
  {
  }
}
Itay
You are correct. However that doesn't matter in this case. It was just to demonstrate that the function can be overriden. I don't know why you were downvoted. I upvoted to balance.
the_drow
The code you've provided won't compile either - your virtual function has no return type and your comment isn't a comment.
Dan Puzey
I guess some badge collector downvoted me for a badge. :)
Itay
Dan Puzey: just followed the question style :P
Itay
A: 

As Vilx- said, I guess the better way to do this kind of stuff is to use Aspect Oriented Programming.

This would help you with the "entangled code" (ie. calling an event in a method that shouldn't have this responsibility) and "scattered code" (ie. calling the same event in a lot of methods, duplicating your code) problems.

You should take a look at postsharp, it has a free community edition.

mverardo