2008-10-01 1 views
11

Когда нужно делать следующее?Когда вы должны переопределять OnEvent, а не подписываться на событие при наследовании

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 
    } 
} 

ответ

9

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

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

+0

Я согласен, переопределить FTW – mmcdole 2008-10-01 19:39:15

+0

Интересно, что принципы дизайна утверждают, что при создании виртуального OnFoo (), соответствующее событие Foo должно быть запущено, даже если нисходящий класс не вызывает base.OnFoo()! Хотя это было бы довольно неудобно. – 2008-10-01 23:04:04

+0

@Matt: private void RaiseFoo() { /* Call OnFoo для производных классов */ this.OnFoo(); /* Raise foo event (работает, даже если base.OnFoo никогда не вызывает производные классы) */ ... } } protected virtual void OnFoo() {/ * ничего не делает * /} – 2008-10-12 23:03:18

6

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

0

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

0

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

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

Например, недавно я выкатил класс списка MRU. В нем было несколько элементов управления ToolStripMenuItem, чье событие клика я использовал. После того, как событие click было уничтожено, я затем поднял событие своего класса. (see that source code here)

0

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

3

Помните, что (хотя бы в .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 
    } 
} 
Смежные вопросы