Когда следует переопределять OnEvent, а не подписываться на событие при наследовании - PullRequest
13 голосов
/ 01 октября 2008

Когда нужно делать следующее?

class Foo : Control
{
    protected override void OnClick(EventArgs e)
    {
        // new code here
    }
}

В отличие от этого?

class Foo : Control
{
    public Foo()
    {
        this.Click += new EventHandler(Clicked);
    }

    private void Clicked(object sender, EventArgs e)
    {
        // code
    }
}

Ответы [ 6 ]

9 голосов
/ 01 октября 2008

Переопределение, а не присоединение делегата приведет к более эффективному коду, поэтому обычно рекомендуется делать это всегда, где это возможно. Для получения дополнительной информации см. эту статью MSDN . Вот соответствующая цитата:

Также защищенный метод OnEventName позволяет производным классам переопределять событие без присоединения делегата к Это. Производный класс всегда должен вызывать метод OnEventName базы класс, чтобы убедиться, что зарегистрирован делегаты получают мероприятие.

8 голосов
/ 01 октября 2008

Событие для внешних подписчиков. Когда вы получаете какой-то элемент управления, всегда переопределяйте метод OnEvent вместо подписки на событие. Таким образом, вы можете быть уверены, что ваш код вызывается, потому что фактическое событие вызывается, когда вы вызываете base.OnEvent (), и вы можете вызывать это перед вашим кодом, после вашего кода, в середине вашего кода или не в все. Затем вы можете также реагировать на возвращаемые значения из события (т.е. измененные свойства в объекте EventArgs).

3 голосов
/ 02 октября 2008

Имейте в виду, что (по крайней мере, в .NET 2.0) я нашел несколько мест в структуре (в частности, в классе DataTable), где метод OnFoo вызывается только , когда соответствующее событие Foo было обрабатываются! Это противоречит рекомендациям по проектированию каркаса, но мы застряли с ним.

Я справился с этим, обработав событие с помощью фиктивного обработчика где-то в классе, например:

public class MyDataTable : DataTable
{
    public override void EndInit()
    {
        base.EndInit();
        this.TableNewRow += delegate(object sender, DataTableNewRowEventArgs e) { };
    }

    protected override void OnTableNewRow(DataTableNewRowEventArgs e)
    {
        base.OnTableNewRow(e);
        // your code here
    }
}
0 голосов
/ 01 октября 2008

Подписка на событие предназначена для элемента управления для отслеживания событий на другом элементе управления. Для мониторинга вашего собственного события хорошо подходит OnClick. Однако обратите внимание, что Control.OnClick обрабатывает эти подписанные события, поэтому обязательно вызовите его в переопределении.

0 голосов
/ 01 октября 2008

Унаследованный класс никогда не должен подписываться на свои собственные события или события своего базового класса.

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

Например, я недавно развернул класс MRU List. В нем было несколько элементов управления ToolStripMenuItem, чье событие щелчка я использовал. После того, как это событие щелчка было использовано, я поднял событие своего класса. ( см. Этот исходный код здесь )

0 голосов
/ 01 октября 2008

Если вы переопределяете, как комментарии Кента Бугаарта, вам нужно быть осторожным, чтобы перезвонить base.OnClick, чтобы разрешить вызовы событий

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