2016-07-22 6 views
0

У меня есть родительский класс, который запускает событие для производных классов. Проблема в том, что обработчик события всегда нулел.Наследование обработчика событий

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 событие в родительском классе утратившим все дни поэтому никогда не увольняют. Спасибо за любую помощь.

+0

Для участия в мероприятиях используйте делегаты 'EventHandler '. Это по соглашению в C#. – dymanoid

+2

Я не вижу причины, по которой событие не может быть установлено. Просьба привести несколько примеров того, как вы создаете классы. – dymanoid

+0

@x Но база. не требуется, поскольку производный класс не имеет события onbufferready, поэтому автоматически переходит к родительскому – Luca

ответ

1

Я мог бы быть неправильно, но вы думали о том, чтобы это событие статический?

public delegate void BufferReadyHandler(string str); 
public static event BufferReadyHandler OnBufferReady; 
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); 

     ... 
    } 
} 
+0

Базовый класс PluginClass является абстрактным, это что-то меняет? – Luca

+0

@ Luca no, ничего не меняет. –

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"); 
    } 
} 
+0

Благодарим за помощь. Простите мою тупость, но ... что отличает мой код? – Luca

+0

@ Luca ничего, что означает, что ваша проблема в коде, который вы нам не показывали. –

+0

Я сомневаюсь, что это проблема, но две вещи: ваш код объявил класс Plugin, но потом унаследовал класс ClassPlugin. И что вызывает событие DataReceived? Вы видели, как я создал ClassIO, а затем вручную назвал DataReceived. –

0

Я не понимаю, почему вы хотели бы работать с событиями в первую очередь для связи между родительским и производным классами.

Если вам нужно это сообщение, вам будет лучше с помощью (абстрактного) метода в базовом классе, который вы реализуете в своих производных классах.

Если вам нужна связь ко всем экземплярам производных типов, вы должны изучить композицию вместо наследования. Создайте экземпляр менеджера, который содержит ссылки на список экземпляров этого базового типа и вызывает определенный метод для каждого из них в случае «события».

Смежные вопросы