2009-03-12 26 views
0

Ich habe eine Schnittstelle wie so definiert:Vererbung & Events

public interface IRipper 
{ 
    IRipperHost Host { get; set; } 

    void Rip(FileStream stream); 

    event RipperEventHandler OnStart; 
    event RipperEventHandler OnComplete; 
    event RipperEventHandler OnProgressChanged;   
} 

public delegate void RipperEventHandler(object sender, RipperEventArgs e); 

und eine Basisklasse, die implementiert, die eine Schnittstelle

public class RipperBase : IRipper 
{ 

    public void Rip(FileStream stream) 
    { 
     throw new System.NotImplementedException(); 
    } 
    public event RipperEventHandler PostRipEvent; 
    event RipperEventHandler IRipper.OnComplete 
    { 
     add 
     { 
      if (PostRipEvent != null) 
      { 
       lock (PostRipEvent) 
       { 
        PostRipEvent += value; 
       } 
      } 
      else 
      { 
       PostRipEvent = value; 
      } 
     } 
     remove 
     { 
      if (PostRipEvent != null) 
      { 
       lock (PostRipEvent) 
       { 
        PostRipEvent -= value; 
       } 
      } 
     } 
    } 
    ... and so on 
} 

Meine Frage ist, wie würde Sie vererben RipperBase und überschreiben Sie die BaseClass Rip-Methode. In der Realität sollte diese Funktion abstrakt sein - aber ich weiß nicht, wie ich das mit Schnittstellen machen soll.

Wie kann ich auch den Basisklassen-Event-Handler aus der von RipperBase abgeleiteten Klasse aufrufen? Ich habe versucht, diesen

RipperEventHandler handler = PreRipEvent; 
    if (handler != null) 
    { 
     handler(this, new RipperEventArgs { Message = "Started Ripping file to CSV!" }); 
    } 

    handler = RipProgEvent; 

dies aber ich bin immer das „Ereignis nur auf der linken Seite von + = oder erscheinen kann -. =“ Fehler

jede Hilfe würde sehr geschätzt werden! Ich versuche, dies so skalierbar wie möglich zu machen.

Antwort

1

geben ich es so tun würde:

public abstract class RipperBase : IRipper 
    { 
     public void Rip(Filestream fs) 
     { 
      RipCore (fs); 
      OnCompleted(); 
     } 

     protected abstract void RipCore(Filestream fs); 

     public event EventHandler<RipperEventArgs> Completed; 

     protected void OnCompleted 
     { 
      if(Completed != null) 
      { 
       // TODO: make this Threadsafe. 
       Completed (this, new RipperEventArgs(...)); 
      } 
     } 
} 

Ich habe die Klasse als abstrakt deklariert, da ich annehme, dass Sie Objekte von RipperBase nicht instanziieren können?

Klassen, die von RipperBase erben, müssen die RipCore-Methode überschreiben und die richtige Funktionalität implementieren. Rip ist die Methode, die die RipCore-Methode aufruft und den Completed-Eventhandler aufruft. (Vielleicht willst du das nicht tun, ich weiß nicht).

Sie können auch sicherstellen, dass die Rip-Methode die RipCore-Methode in einem anderen Thread aufruft, wenn Sie möchten.

Für die Ereignisse, ich erstellen eine geschützte Methode in der Basisklasse, die verwendet werden kann, um die Ereignisse zu erhöhen. Wenn Sie das Ereignis in einer Unterklasse auslösen möchten, rufen Sie diese Methode einfach auf.

+0

Vielen Dank! –

1

erklären die Methode in der Basisklasse als virtuell, wie:

public virtual void Rip(FileStream stream) 
{ 
    throw new System.NotImplementedException(); 
} 

und in der speziellen Klasse:

public override void Rip(FileStream stream){} 

Für den Fall, tun dies auf der Basis:

protected void FireASpecificEvent(SomeClass someArguments) 
{//fire event normally 
} 
0

Ich weiß nicht, ob das helfen kann, aber ich denke, Sie sollten die Rip-Funktion mit virtuellem Zugriff markieren, so dass es überschreibbar sein kann,

und über das Ereignis, versuchen Sie vielleicht, wissen nicht, eine Methode auf der Basisklasse OnPreRipEventFired() zu schaffen, nur Ideen

0

Vielleicht wäre es besser, wenn Sie eine abstrakte abstrakte Basisklasse erstellen.

Verwenden Sie auch den EventHandler <> generischen Typ für Ihre Ereignisse, anstatt einen anderen Typ (RipperEventHandler) zu deklarieren. Zum Beispiel:

+0

true über den generischen Eventhandler. –

+0

Geist Entsendung ein Beispiel für die Verwendung des generischen Typs? –

+0

Nur ein Beispiel hinzugefügt. – Sean