views:

191

answers:

1

Hi Guys,
I have an interface with several events
I have base class implementing the interface
I have third class extending the base class (let's call it theConcreteClass)

problem: when i do something like: IMyInterface i = new theConcreteClass() and then i subscribe to any of the events (i.someEvent+=some_handler;) the event handlers never invoked because (probably) the event subscription was assigned to the base class and not to the concrete class even though the new() operator created the concrete class.

hope it was clear :)
any suggestions?

thanks,
Adi Barda

+4  A: 

What you are describing should work as expected.

Have you declared the events again in the concrete class hiding the base implementations?

Your code should be:

public interface IInterface
{
    event EventHandler TestEvent;
}

public class Base : IInterface
{
    public event EventHandler TestEvent;
}

public class Concrete : Base
{
   //Nothing needed here
}


To answer your comment:

Standard practice is to place a method on the base class:

public class Base : IInterface
{
    public event EventHandler TestEvent;

    protected virtual void OnTestEvent()
    {
        if (TestEvent != null)
       {
           TextEvent(this, EventArgs.Empty);
       }
    }
}

public class Concrete : Base
{
   public void SomethingHappened()
   {
       OnTestEvent();
   }
}

This pattern helps centralise any logic for firing the event, testing for null etc, and makes it easy to hook into the time that the event fires in child classes by overriding the method.

Martin Harris
but then how do i invoke the event from within the concrete class?
Adi Barda
this.TestEvent() or base.TestEvent() - whatever fits your needs.
Daniel Brückner
@Adi, you can only trigger the event from the class that declared it. That's why many implementation provide a protected method (only accessible from those who inherit) named OnEventName which will trigger the event with event arguments.
Simon Svensson
in the concrete class i cannot test for !=null and cannot invoke the event - Martin your answers was wrong (doesn't compile). I wonder why microsoft put that restriction.
Adi Barda
I edited my answer when I realised I was being stupid and it wouldn't compile. The reason for the restriction is to allow two layers of access control, one for the ability to register for the event (the public event itself) and one for the ability to fire the event (the private default, or the added protected method). If you only required access to the event to fire it then any class would be able to fire any event.
Martin Harris
There's still a race condition between checking TestEvent != null and the invocation of TestEvent (which is misspelled btw). Store it in a temporary variable that you use in the check and invocation.
Simon Svensson