public Event in abstract class

11,352

Solution 1

This approach could be dangerous, see below for a better one

Events can only be raised (or checked for null apparently) from within the declaring class. This protection extends to derived classes.

Thus, the solution is to re-declare the event as an implementation of an abstract event in the base class. Then you can still use it via a base class reference as you want, and raise/use it in the derived class:

public abstract class AbstractClass
{
    public abstract event Action ActionEvent;
}

public class MyClass : AbstractClass
{
    public override event Action ActionEvent;

    private void SomeMethod()
    {
        //Want to access ActionEvent-- Now you can!
        if (ActionEvent != null)
        {
        }

    }
}

Correct approach

MSDN Suggests that this approach may not be handled by the compiler correctly. Instead you should provide protected methods so derived classes can check for null, invoke the event, etc:

public abstract class AbstractClass
{
    public event Action ActionEvent;
    protected bool EventIsNull()
    {
        return ActionEvent == null; 
    }
}

public class MyClass : AbstractClass
{
    private void SomeMethod()
    {
        //Want to access ActionEvent-- Now you can!
        if (!EventIsNull())
        {}
    }
}

Solution 2

An often used pattern for this is something like the below (you'll see a lot of it in the classes in the System.Windows.Forms namespace).

public abstract class MyClass
{
    public event EventHandler MyEvent;

    protected virtual void OnMyEvent(EventArgs e)
    {
        if (this.MyEvent != null)
        {
            this.MyEvent(this, e);
        }
    }
}

You would then use it in a derived class like this, optionally extending the behaviour:

public sealed class MyOtherClass : MyClass
{
    public int MyState { get; private set; }

    public void DoMyEvent(bool doSomething)
    {
        // Custom logic that does whatever you need to do
        if (doSomething)
        {
            OnMyEvent(EventArgs.Empty);
        }
    }

    protected override void OnMyEvent(EventArgs e)
    {
        // Do some custom logic, then call the base method
        this.MyState++;

        base.OnMyEvent(e);
    }
}
Share:
11,352
user421719
Author by

user421719

Updated on July 23, 2022

Comments

  • user421719
    user421719 almost 2 years

    I have event declared in abstract class:

    public abstract class AbstractClass
    {
        public event Action ActionEvent;
    }
    
    public class MyClass : AbstractClass
    {
        private void SomeMethod()
        {
            //Want to access ActionEvent-- Not able to do so
            if (ActionEvent != null)
            {
            }
    
        }
    }
    

    I wanted to access this base class event in derived. Further I wanted to access this event in some other derived class of MyClass:

    MyClass.ActionEvent += DerivedMethod()
    

    Please help me understand how to work with event defined in abstract classes.