2016-07-22 74 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但是基地。是沒有必要的,因爲派生類沒有緩衝區事件,所以自動轉到父項 – 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不,不會改變任何。 –

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

我不明白你爲什麼想首先在事件中使用父類和派生類之間的通信。

如果您需要此通信,您可以更好地使用您的基類中的(抽象)方法,並在派生類中實現該方法。

如果您需要與派生類型的所有實例進行通信,則應該考慮組合而不是繼承。創建某種管理器實例,該實例持有對該基本類型實例列表的引用,並在發生「事件」的情況下在每個實例上調用某種方法。