在C#6中调用基本事件处理程序

时间:2016-07-26 09:54:18

标签: c# event-handling

我有一个简单的抽象类:

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();
}

一个简单的子类:

class BubbleSort : Lesson
{
    public override void Do()
    {
        base.Speak?.Invoke(this, new SpeakEventArgs { Message = OpeningMessage });
    }
}

子类使用C#6空条件运算符?.。此代码提供错误

  

活动&#39; Lesson.Speak&#39;只能出现在+ =或 - =的左侧(除非在类型&#39;课程&#39;中使用)

当然,作为一个小班,我在这里的课程&#39;课程&#39;?如何在子类中调用基类事件?

3 个答案:

答案 0 :(得分:1)

不能直接从定义它的类之外调用一个事件,即使是从一个子类。

解决方案:使用protected方法启动它:

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 });
    }
}

答案 1 :(得分:0)

您不能在除

中声明的类之外的任何类中调用事件

相反,我会建议在你的基类中创建一个执行所需检查的raise方法,然后为你引发事件

protected void raiseSpeak(SpeakEventArgs args)
{
    this.Speak?.Invoke(sender, args);
}

或者在您的情况下,只需从do中删除摘要并在课程类中的do方法中引发事件,然后您可以覆盖它以获得额外的功能

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
    }
}

答案 2 :(得分:0)

You will have to provide a raise method in your abstract class,例如:

chunkId

然后您可以选择覆盖,例如:

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);
    }
}