2016-07-22 5 views
0

派生クラスに対してイベントを発生させる親クラスがあります。問題は、イベントハンドラが常にnullであることです。イベントハンドラの継承

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

@ルーカノは、それを変更しません。 –

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

@ルーカ無し、あなたの問題はあなたが私たちに示していないコードにあることを意味します。 –

+0

私はこれが問題だとは思っていませんが、あなたのコードはクラスPluginを宣言しましたが、クラスClassPluginを継承しました。また、DataReceivedイベントは何が起こりますか?あなたはClassIOをどのようにインスタンス化し、手動でDataReceivedを呼び出すかを見てきました。 –

0

親クラスと派生クラス間の通信のためにイベントを最初に使用する理由を理解できません。

この通信が必要な場合は、派生クラスに実装する基本クラスの(抽象)メソッドを使用する方がよいでしょう。

派生型のすべてのインスタンスへの通信が必要な場合は、継承の代わりに合成を調べる必要があります。その基本型のインスタンスのリストへの参照を保持する何らかの種類のマネージャーインスタンスを作成し、 'イベント'の場合はそれぞれの特定のメソッドを呼び出します。