Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why events can't be used in the same way in derived classes as in the base class in C#?

Tags:

c#

events

In following code, I want to extend the behaviour of a class by deriving/subclassing it, and make use of an event of the base class:

public class A {     public event EventHandler SomeEvent;      public void someMethod()     {         if(SomeEvent != null) SomeEvent(this, someArgs);     } }  public class B : A {     public void someOtherMethod()     {         if(SomeEvent != null) SomeEvent(this, someArgs); // << why is this not possible? //Error: The event 'SomeEvent' can only appear on the left hand side of += or -=  //(except when used from within the type 'A')     } } 

Why isn't it possible?

And what is the common solution for this kind of situation?

like image 820
mr_georg Avatar asked Oct 31 '08 14:10

mr_georg


People also ask

How do you raise base class events in derived classes?

To do this, you can create a protected invoking method in the base class that wraps the event. By calling or overriding this invoking method, derived classes can invoke the event indirectly. Do not declare virtual events in a base class and override them in a derived class.

What is the connection between the base class and the derived class?

Inheritance enables you to create new classes that reuse, extend, and modify the behavior defined in other classes. The class whose members are inherited is called the base class, and the class that inherits those members is called the derived class. A derived class can have only one direct base class.

Which class is used to inherited events?

Inheritance was invented in 1969 for Simula and is now used throughout many object-oriented programming languages such as Java, C++, PHP and Python. An inherited class is called a subclass of its parent class or super class.

Why do we use derived classes?

Usually you use a derived class when an existing class provides members that the new class can use, or when you want to extend or embellish existing class properties and methods. This is called inheritance: the new class inherits, and has direct access to, all Public and Private members of the existing base class.


2 Answers

Others have explained how to get round the issue, but not why it's coming up.

When you declare a public field-like event, the compiler creates a public event, and a private field. Within the same class (or nested classes) you can get at the field directly, e.g. to invoke all the handlers. From other classes, you only see the event, which only allows subscription and unsubscription.

like image 69
Jon Skeet Avatar answered Sep 21 '22 15:09

Jon Skeet


The standard practice here is to have a protected virtual method OnSomeEvent on your base class, then call that method in derived classes. Also, for threading reasons you will want to keep a reference to the handler before checking null and calling it.

For an explanation of the why read Jon Skeet's answer or the C# specification which describes how the compiler automatically creates a private field.

Here is one possible work around.

public class A {     public event EventHandler SomeEvent;      public void someMethod()     {         OnSomeEvent();     }      protected void OnSomeEvent()     {         EventHandler handler = SomeEvent;         if(handler != null)             handler(this, someArgs);     } }  public class B : A {     public void someOtherMethod()     {         OnSomeEvent();     } } 

Edit: Updated code based upon Framework Design Guidelines section 5.4 and reminders by others.

like image 37
Todd White Avatar answered Sep 18 '22 15:09

Todd White