tags:

views:

130

answers:

4

Hello everyone I have an interface defined like so:

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

and a base class that implements that interface

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
}

My question is how would you inherit from RipperBase and override the BaseClass Rip method. in reality that function should be abstract - but i don't know how to do that with interfaces.

Also how can i call the base classes event handler from the class derived from RipperBase? I tried this

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

    handler = RipProgEvent;

this but I'm getting the "event can only appear on the left hand side of += or -=." error

any help would be greatly appreciated! I'm trying to make this as scalable as possible.

+1  A: 

declare the method in the base class as virtual, like:

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

and in the specific class:

public override void Rip(FileStream stream){}

For the event, do this on the base:

protected void FireASpecificEvent(SomeClass someArguments)
{//fire event normally
}
eglasius
A: 

I don't know if this can help, but i think you should tag the Rip function with virtual access, so it can be overridable ,

and about the event, maybe you can try creating a method on the base class OnPreRipEventFired(), don't know, just giving ideas

Jhonny D. Cano -Leftware-
+1  A: 

I would do it like this:

    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( ... ) );
           }
        }
}

I've declared the class as abstract, since I presume that you cannot instantiate objects from RipperBase ?

Classes that inherit from RipperBase have to override the RipCore method, and implement the correct functionality. Rip is the method that calls the RipCore method, and it also raises the Completed eventhandler. (Maybe you do not want to do this, i dunno).

You can also make sure that the Rip method calls the RipCore method on another thread if you want.

For the events, I create a protected method in the base class that can be used to raise the events. If you want to raise the event in a subclass, you just call this method.

Frederik Gheysels
Thank you very much!
Michael G
A: 

Perhaps you'd be better off making a Ripper abstract base class.

Also, use the EventHandler<> generic type for your events rather than declare another type (RipperEventHandler). For example:

event EventHandler<RipperEventArgs> OnStart;
Sean
true about the generic eventhandler.
Frederik Gheysels
mind posting an example of using the generic type?
Michael G
Just added an example.
Sean