事件处理程序继承

时间:2016-07-22 13:47:31

标签: c# events derived-class base-class

我有一个父类正在向派生类触发事件。问题是事件处理程序总是为空。

Class Plugin()
{
    public delegate void BufferReadyHandler(string str);
    public event BufferReadyHandler OnBufferReady;
    public ClassPlugin(eGuiType _guyType)
    {
        GuiType = _guyType;
    }
    protected void Sp_DataReceived_Parent(object sender, SerialDataReceivedEventArgs e)
    {
        strCommonBuffer += serial.ReadExisting();
        if (strCommonBuffer.Contains("\r\n"))
        {
            if (OnBufferReady != null) <<-------NULL
                OnBufferReady(strCommonBuffer);
            strCommonBuffer = string.Empty;
        }
    }
}

然后有一些链接到该事件的派生类:

class ClassIO : ClassPlugin
{
    public ClassIO(eGuiType _guyType) : base(_guyType)
    {
        ...
        OnBufferReady += ClassIO_OnBufferReady;
    }

    private void ClassIO_OnBufferReady(string str)
    {
        ...
    }
}

问题是父类中的OnBufferReady事件总是为空,因此从不触发。 谢谢你的帮助。

4 个答案:

答案 0 :(得分:1)

我可能错了,但你有没有想过让事件变得静止?

public delegate void BufferReadyHandler(string str);
public static event BufferReadyHandler OnBufferReady;

答案 1 :(得分:0)

我不确定你为什么遇到这个问题,我怀疑它与你没有向我们展示的代码有关。但是在这种情况下,我根本不会让孩子订阅该事件,而是创建一个受保护的方法来引发孩子可以覆盖的事件。

以下是我将如何实现该类。

public class BufferReadyEventArgs : EventArgs
{
    public BufferReadyEventArgs(string commonBuffer)
    {
        CommonBuffer = commonBuffer;
    }
    public string CommonBuffer {get; private set;}
}

Class Plugin()
{
    public event EventHandler<BufferReadyEventArgs> OnBufferReady;
    public ClassPlugin(eGuiType _guyType)
    {
        GuiType = _guyType;
    }
    protected void Sp_DataReceived_Parent(object sender, SerialDataReceivedEventArgs e)
    {
        strCommonBuffer += serial.ReadExisting();
        if (strCommonBuffer.Contains("\r\n"))
        {
            RaiseOnBufferReady(strCommonBuffer);
            strCommonBuffer = string.Empty;
        }
    }

    protected virtual void RaiseOnBufferReady(string commonBuffer)
    {
        var temp = OnBufferReady;
        if(temp != null)
            temp(this, new BufferReadyEventArgs(commonBuffer));
    }
}

class ClassIO : ClassPlugin
{
    public ClassIO(eGuiType _guyType) : base(_guyType)
    {
        ...
    }

    protected override void RaiseOnBufferReady(string commonBuffer)
    {
        base.RaiseOnBufferReady(commonBuffer);

        ...
    }
}

答案 2 :(得分:0)

以下是基于您的代码的工作示例:

using System;
using System.Collections.Generic;

public class MyClass
{
    public static void Main()
    {
        ClassIO c = new ClassIO();
        c.DataReceived();

        Console.ReadLine();
    }
}

public class ClassPlugin
{
    public delegate void BufferReadyHandler(string str);
    public event BufferReadyHandler OnBufferReady;

    public ClassPlugin()
    {
    }

    public void DataReceived()
    {       
        if (OnBufferReady != null) {
            OnBufferReady("Calling OnBufferReady");
        }
    }
}

public class ClassIO : ClassPlugin
{
    public ClassIO() : base()
    {
        OnBufferReady += ClassIO_OnBufferReady;
    }

    private void ClassIO_OnBufferReady(string str)
    {
        Console.WriteLine("Inside ClassIO_OnBufferReady");
    }
}

答案 3 :(得分:0)

我不明白为什么你想首先处理事件,以便在父类和派生类之间进行通信。

如果您需要这种通信,那么您最好使用在派生类中实现的基类中的(抽象)方法。

如果需要与派生类型的所有实例进行通信,则应该查看组合而不是继承。制作某种管理器实例,该实例保存对该基本类型实例列表的引用,并在发生事件时对每个实例调用某种方法。