Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Enforcing implementation of events in derived abstract classes

I am trying to create what I am thinking of as a translation class, so that my program can speak to a variety of target platforms. Each platform will be handled by a separate implementation of an abstract class. I have pared things down for the sake of simplicity.

I have an abstract class, with a couple of abstract methods:

abstract class ControllerBase
{
    public abstract bool EnableDTMFDetection(string CallID, Party Party);
    public abstract bool DisableDTMFDetection(string CallID, Party Party);
}

Subsequently a class (classes) which derive from ControllerBase, and fully implement those methods:

class PlatformOne : ControllerBase
{
    public override bool EnableDTMFDetection(string CallID, Party Party)
    {
        // Do Stuff
        return true;
    }

    public override bool DisableDTMFDetection(string CallID, Party Party)
    {
        // Do Stuff
        return true;
    }
}

So far so good. For PlatformOne I am forced to define each of those methods, prescribing how I will send an outgoing message to my target platform.

It is the incoming events that have got me. I need to be able to raise events from within my derived classes. When I add the following to controllerbase:

    public delegate void MyEventHandler(object sender, EventArgs e);
    public event MyEventHandler MyEvent;

It compiles fine, but I can't raise the event from within my derived class without the error: "The event 'ControllerBase.MyEvent' can only appear on the left hand side of += or -= (except when used from within the type 'ControllerBase')"

So, a) How do I raise my event from within my derived class, and b) can anyone suggest a mechanism for enforcing the wiring up of specified events from within my derived class (a la abstract functions or interface methods). Thank you call :)

like image 222
Adrian Hand Avatar asked Oct 04 '10 16:10

Adrian Hand


People also ask

Can you have implementation in abstract class?

An abstract class can have an abstract method without body and it can have methods with implementation also. abstract keyword is used to create a abstract class and method.

How abstract method is implemented in derived class?

The implementation of an abstract method is done by a derived class. When the derived class inherits the abstract method from the abstract class, it must override the abstract method. This requirment is enforced at compile time and is also called dynamic polymorphism.

Is it mandatory to override abstract method in derived class?

It is necessary to override all the methods which are declared as abstract . you cannot skip the non-concrete methods. If you really want to do then make your class as abstract.

Is it mandatory to implement abstract method in derived class C#?

An abstract method must be implemented in all non-abstract classes using the override keyword. After overriding, the abstract method is in the non-Abstract class. We can derive this class in another class, and again we can override the same abstract method with it.


2 Answers

The simplest way of doing this is to write a method in your base class to raise it:

protected void OnMyEvent(EventArgs e)
{
    // Note the copy to a local variable, so that we don't risk a
    // NullReferenceException if another thread unsubscribes between the test and
    // the invocation.
    EventHandler handler = MyEvent;
    if (handler != null)
    {
        handler(this, e);
    }
}

You may want to make it a virtual method so you can override it in derived classes... it depends on your use case.

Note that this isn't forcing an implementation of anything in the derived class - but I think it's what you actually want.

like image 164
Jon Skeet Avatar answered Sep 22 '22 17:09

Jon Skeet


The standard pattern is to add an On<EventName> virtual protected method to raise an event

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

Also bear in mind that events can be made abstract or virtual:

public abstract event MyEventHandler MyEvent;

although this is only generally used in interfaces, which might be better for your ControllerBase depending on your exact requirements:

public interface IController {
    event MyEventHandler MyEvent;
    bool EnableDTMFDetection(string CallID, Party Party);
    bool DisableDTMFDetection(string CallID, Party Party);
}

public PlatformOne : IControllerBase

    // yadda yadda...

    public event MyEventHandler MyEvent;

    // members of PlatformOne can invoke MyEvent as a normal delegate
}
like image 23
thecoop Avatar answered Sep 25 '22 17:09

thecoop