Наследование и события - PullRequest
0 голосов
/ 12 марта 2009

У меня есть интерфейс, определенный так:

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 и переопределяли метод BaseClass Rip. в действительности эта функция должна быть абстрактной - но я не знаю, как это сделать с интерфейсами.

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

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

    handler = RipProgEvent;

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

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

Ответы [ 4 ]

1 голос
/ 12 марта 2009

Я бы сделал это так:

    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 в другом потоке, если хотите.

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

1 голос
/ 12 марта 2009

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

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 голосов
/ 12 марта 2009

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

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

event EventHandler<RipperEventArgs> OnStart;
0 голосов
/ 12 марта 2009

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...