2016-07-22 13 views
0

Ich habe eine Elternklasse, die ein Ereignis zu abgeleiteten Klassen auslöst. Das Problem ist, dass der Event-Handler immer null ist.Event-Handler-Vererbung

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

dann gibt es einige abgeleitete Klassen, die mit diesem Ereignis verknüpft sind:

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

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

das Problem ist, dass das OnBufferReady Ereignis in der übergeordneten Klasse alway null ist und daher nie gebrannt. Danke für jede Hilfe.

+0

Verwenden Sie 'EventHandler ' -basierte Delegaten für Ereignisse. Dies ist per Konvention in C#. – dymanoid

+2

Ich kann den Grund nicht sehen, warum das Ereignis nicht festgelegt werden konnte. Bitte geben Sie einige Beispiele an, wie Sie die Klassen instanziieren. – dymanoid

+0

@x Aber Basis. ist nicht notwendig, da die abgeleitete Klasse kein onbufferready-Ereignis hat, also automatisch zum übergeordneten Element geht – Luca

Antwort

1

Ich könnte falsch sein, aber gedacht haben Sie das Ereignis statisch zu machen?

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

Ich bin mir nicht sicher, warum Sie dieses Problem haben, ich vermute, dass es etwas mit dem Code zu tun hat, den Sie uns nicht gezeigt haben. In dieser Situation würde das Kind das Ereignis jedoch überhaupt nicht abonnieren und stattdessen eine geschützte Methode erstellen, die das Ereignis auslöst, das das Kind überschreiben kann.

Hier ist, wie ich die Klasse implementieren würde.

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

Die Basisklasse PluginClass ist abstrakt ändert das etwas? – Luca

+0

@Luca nein, ändert nichts davon. –

0

ist hier ein funktionierendes Beispiel auf dem Code basiert:

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

Vielen Dank für Ihre Hilfe. Verzeihen Sie meine Dummheit, aber ... was ist anders als mein Code? – Luca

+0

@Luca nichts, was bedeutet, dass Ihr Problem in dem Code ist, den Sie uns nicht gezeigt haben. –

+0

Ich bezweifle, dass dies das Problem ist, aber zwei Dinge, Ihr Code deklariert Klasse Plugin aber geerbt Klasse ClassPlugin. Und was löst das DataReceived-Ereignis aus? Sie haben gesehen, wie ich ClassIO instanziiert und dann DataReceived manuell aufgerufen habe. –

0

Ich verstehe nicht, warum Sie zwischen Eltern möchten und Klasse abgeleitet für die Kommunikation in erster Linie mit Ereignissen arbeiten.

Wenn Sie diese Kommunikation benötigen, sind Sie besser mit einer (abstrakten) Methode in Ihrer Basisklasse, die Sie in Ihren abgeleiteten Klassen implementieren.

Wenn Sie eine Kommunikation zu allen Instanzen abgeleiteter Typen benötigen, sollten Sie sich die Komposition und nicht die Vererbung ansehen. Mache eine Art Manager-Instanz, die Verweise auf eine Liste von Instanzen dieses Basistyps enthält, und rufe im Falle eines "Ereignisses" eine bestimmte Methode auf.