2009-03-12 2 views
0

Я интерфейс, определенный следующим образом:Наследование & События

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

и базовый класс, который реализует этот интерфейс

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 
} 

Мой вопрос, как бы вам унаследуют от RipperBase и переопределить метод Rip BaseClass. в действительности эта функция должна быть абстрактной - но я не знаю, как это сделать с интерфейсами.

Также как я могу вызвать обработчик событий базовых классов из класса, полученного из RipperBase? Я пробовал это

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

    handler = RipProgEvent; 

это, но я получаю «событие может появляться только с левой стороны + = или - =.» ошибка

всякая помощь была бы принята с благодарностью! Я пытаюсь сделать это максимально масштабируемым.

ответ

1

Я хотел бы сделать это следующим образом:

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

Я объявил класс абстрактным, так как я предполагаю, что вы не можете создавать объекты из RipperBase?

Классы, которые наследуют от RipperBase, должны переопределить метод RipCore и реализовать правильную функциональность. Rip - это метод, который вызывает метод RipCore, а также вызывает обработчик события Completed. (Может быть, вы не хотите этого делать, я не знаю).

Вы также можете убедиться, что метод Rip вызывает метод RipCore в другом потоке, если вы хотите.

Для событий я создаю защищенный метод в базовом классе, который можно использовать для поднять события. Если вы хотите поднять событие в подклассе, вы просто вызываете этот метод.

+0

Большое спасибо! –

1

объявить метод в базовом классе как виртуальная, как:

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

и в конкретном классе:

public override void Rip(FileStream stream){} 

В случае, сделать это на базе:

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

Я не знаю, может ли это помочь, но я думаю, что вы должны пометить функцию Rip виртуальным доступом, поэтому она может быть переопределяемой,

и о событии, может быть, вы можете попробовать создать метод на базовом классе OnPreRipEventFired(), не знаю, просто дать идеи

0

Возможно, вам будет лучше сделать базовый класс Ripper.

Кроме того, используйте EventHandler <> общий тип для ваших событий, вместо объявления другого типа (RipperEventHandler). Например:

event EventHandler<RipperEventArgs> OnStart; 
+0

true об общем манипуляторе событий. –

+0

mind Опубликовать пример использования универсального типа? –

+0

Просто добавил пример. – Sean

Смежные вопросы