Home > .Net, C# > Creating event in Abstract class and Raising this event from derived class

Creating event in Abstract class and Raising this event from derived class

I won’t explain here hat is Abstract class and why we would like to use it in our Object orientated programming. But I want to discuss some issues that come when we are using events in the base Abstract class.

When we want to create event in abstract class which intended to be raised from derived classes, we discover right away that such code won’t compile.
See following code example where created simple abstract class which have public event. Simple derived class that tries to fire this event from DoMyLogic() method.

public abstract class AbstractSample
    {
        public event EventHandler AbstractEvent;

        public abstract bool IsActionComplete();

        public void Foo()
        {
            //some code 
        }
    }

    public class MyClass : AbstractSample
    {

        public override bool IsActionComplete()
        {
            //implementation
            return true;
        }

        void DoMyLogic()
        {
            //Fire event that was declared in base class
            base.AbstractEvent(this, EventArgs.Empty);//compile error

        }
    }


The event ‘AbstractSample.AbstractEvent’ can only appear on the left hand side of += or -= (except when used from within the type’AbstractSample’)

From this error message we learn that derived class refers to base class event as real event that can be subscribed for. Unfortunately this is not what we need.

I have found two possible solutions that can allow us easily raise event from derived class.

1) Probably the simplest way is to create protected and better virtual method in base Abstract class. This method will be responsible for raising event, and every derived class can use it.
See code sample:

 
        protected virtual void RaiseAbstractEvent(EventArgs e)
        {
            if (AbstractEvent != null)
            {
                AbstractEvent(this, e);
            }
	
        }

And usage will be as following code:

        void DoMyLogic()
        {
            //Fire event that was declared in base class
            //base.AbstractEvent(this, EventArgs.Empty); //compilation error
            base.RaiseAbstractEvent(EventArgs.Empty);

        }

Some disadvantage that if developer who uses Abstract class have to know about this protected method in order to use it.

2) The second solution is to declare event abstract or virtual and every derived class will have to override this event. Same bihaiviour can be achived by using Interface that declare event.

    public abstract class AbstractSample
    {
        public abstract event EventHandler AbstractEvent;

        public abstract bool IsActionComplete();

        public void Foo()
        {
            //some code 
        }

        //protected virtual void RaiseAbstractEvent(EventArgs e)
        //{
            //if (AbstractEvent != null)
            //{
            //    AbstractEvent(this, e);
            //}
	
        //}
    }

    public class MyClass : AbstractSample
    {

        public override bool IsActionComplete()
        {
            //implementation
            return true;
        }

        void DoMyLogic()
        {
            //Fire event that was declared in base class
            //base.AbstractEvent(this, EventArgs.Empty); //compilation error
            //base.RaiseAbstractEvent(EventArgs.Empty);
            if (AbstractEvent != null)
            {
                AbstractEvent(this, EventArgs.Empty);
            }


        }

        public override event EventHandler AbstractEvent;
    }

It’s really simple and nice solutions hope it will help somebody.

Categories: .Net, C# Tags:
  1. April 28th, 2013 at 03:01 | #1

    I agree with most of the concepts you have available within your publish. They’re pretty begging and will unquestionably work. On the other hand, your articles are extremely fast to start. May you please expand all of them just a little from next occasion? Appreciate this article.

  1. No trackbacks yet.