Действительно ли ошибка переопределять события в C #? - PullRequest
2 голосов
/ 06 октября 2011

Я прочитал в этом вопросе: Переопределяющие события в VB

Даже ошибка переопределять события в C #. Руководство по программированию на C # гласит: Не объявляйте виртуальные события в базовом классе и переопределяйте их в производном классе. Компилятор C # не обрабатывает их правильно в Microsoft Visual Studio 2008, и непредсказуемо, будет ли подписчик на производное событие фактически подписываться на событие базового класса. Интересно, почему класс фреймворка нарушает это правило или даже почему компилятор это допускает.

Я не могу понять, почему ошибочно игнорировать события. Конечно, унаследованный класс всегда может отслеживать событие базового класса и впоследствии предпринимать свои собственные действия, но что если он захочет убедиться, что это первый наблюдатель события, увидевший событие? Что он хочет решить проглотить событие при определенных условиях? Что не так с этим:

    protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
    {
        VerifyActiveCountMatches();
        base.OnCollectionChanged(e);
        InvokePropertyChanged("Count");
    }

Ответы [ 3 ]

7 голосов
/ 06 октября 2011

Это не ошибка , но это может быть плохим дизайнерским решением. Есть большая разница; компилятор не позволит вам избежать ошибки, но он редко критикует ваш дизайн.

Код, который вы указали для OnCollectionChanged, не не переопределяет событие - он переопределяет метод, который вызывает событие. Это совершенно другой вопрос. Событие что-то вроде:

// "Field-like" event - the compiler implements the add/remove and
// creates a backing field.
public event EventHandler Click;

или

// Manually-implemented event; you write the add/remove yourself, and
// create a separate backing variable if necessary.
public event EventHandler Click
{
    add { ... }
    remove { ... }
}

Это фрагменты кода, которые обрабатывают подписку и отмену подписки - и это эти , что совет говорит, что вы не должны переопределять. Вы редко бы хотели бы , и, как говорится в цитируемом тексте, существует множество ситуаций, когда он не будет делать то, что вы хотели, в любом случае.

2 голосов
/ 06 октября 2011

Это не переопределяет событие, вы переопределяете вызывающее событие там (возможно, обработчик, но этот шаблон обычно обозначает защищенный элемент, который используется для вызова обработчика события).

Переопределение события будет выглядеть примерно так:

public override event EventHandler CollectionChanged;
0 голосов
/ 06 октября 2011

Я цитирую this blog:

"Использование события, подобного виртуальному полю, в родительском классе и отсутствие изменения его поведения в переопределяющем производном классе не требуется.Вы можете просто пропустить переопределение в производном классе, чтобы получить желаемое поведение. "

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

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