Reputation: 17527
I have a simple abstract class:
abstract class Lesson
{
public event EventHandler<SpeakEventArgs> Speak;
public string OpeningMessage { get; set; }
public string ClosingMessage { get; set; }
public bool completed { get; private set; } = false;
abstract public void Do();
}
And a simple sub-class:
class BubbleSort : Lesson
{
public override void Do()
{
base.Speak?.Invoke(this, new SpeakEventArgs { Message = OpeningMessage });
}
}
The sub-class uses the C# 6 null-conditional operator ?.
. This code gives the error
The event 'Lesson.Speak' can only appear on the left hand side of += or -= (except when used within the type 'Lesson')
Surely as a sub-class I am here within the type 'Lesson'? How do I do this invocation of the base class event within the sub-class?
Upvotes: 1
Views: 2405
Reputation: 5500
You can't Invoke an event in any class other than the one that it was declared in
instead i would suggest creating a raise method in your base class that performs the required checks then raises the event for you
protected void raiseSpeak(SpeakEventArgs args)
{
this.Speak?.Invoke(sender, args);
}
or in your case just remove the abstract from do and raise the event in the do method in your lesson class, which you can then override for extra functionality
abstract class Lesson
{
public event EventHandler<SpeakEventArgs> Speak;
public virtual void Do()
{
this.Speak?.Invoke(sender, args);
}
}
class BubbleSort : Lesson
{
public override void Do()
{
base.Do();
//do something BubbleSort related
}
}
Upvotes: 1
Reputation:
You will have to provide a raise method in your abstract class, eg:
abstract class Lesson
{
public event EventHandler<SpeakEventArgs> Speak;
public string OpeningMessage { get; set; }
public string ClosingMessage { get; set; }
public bool completed { get; private set; } = false;
abstract public void Do();
protected virtual void RaiseSpeak(object sender, SpeakEventArgs args)
{
this.Speak?.Invoke(sender, args);
}
}
which you then can override optionally, eg:
class BubbleSort : Lesson
{
protected override void RaiseSpeak(object sender, SpeakEventArgs args)
{
// your logic here
base.RaiseSpeak(sender, args);
}
public override void Do()
{
this.RaiseSpeak(this, new SpeakEventArgs() { Message = OpeningMessage });
}
}
Upvotes: 0
Reputation: 48995
You cannot directly invoke an event from outside the class that defines it, even from a sub-class.
Solution: use a protected
method to fire it:
internal abstract class Lesson
{
public event EventHandler<SpeakEventArgs> Speak;
public string OpeningMessage { get; set; }
public string ClosingMessage { get; set; }
public bool completed { get; private set; } = false;
abstract public void Do();
protected void DoSpeak(SpeakEventArgs e)
{
if (this.Speak != null)
{
this.Speak(this, e);
}
}
}
internal class BubbleSort : Lesson
{
public override void Do()
{
base.DoSpeak(new SpeakEventArgs { Message = OpeningMessage });
}
}
Upvotes: 1