День двести двадцать шестой. #BestPractices

Советы по разработке членов типов

Разработка событий

События являются наиболее часто используемой формой обратных вызовов. Существует две группы событий: события, возникающие до изменения состояния системы, называемые пред-событиями, и события, возникающие после изменения состояния, называемые пост-событиями. Например, пред-событие Form.Closing вызывается перед закрытием формы, пост-событие Form.Closed вызывается после закрытия формы.



ИСПОЛЬЗУЙТЕ термин raise для событий вместо fire или trigger.

ИСПОЛЬЗУЙТЕ System.EventHandler<TEventArgs> вместо того, чтобы вручную создавать новые делегаты для использования в качестве обработчиков событий.

⚠️ РАССМОТРИТЕ использование классов, производных от EventArgs, в качестве аргумента события, кроме случаев, когда вы абсолютно уверены, что событию никогда не потребуется передавать какие-либо данные в метод обработки, и в этом случае вы можете напрямую использовать тип EventArgs. Если вы напрямую используете EventArgs, вы никогда не сможете добавить какие-либо данные для передачи в обработчик события без нарушения совместимости. Если вы используете подкласс, даже если изначально он полностью пуст, вы сможете добавлять свойства в подкласс при необходимости.

ИСПОЛЬЗУЙТЕ защищенный виртуальный метод, для вызова каждого события. Это применимо только к нестатическим событиям в открытых классах, но не к структурам, закрытым классам или статическим событиям. Цель такого метода - предоставить производному классу способ обработки события с использованием переопределения. Переопределение - это более гибкий, быстрый и более естественный способ обработки событий базового класса в производных классах. По соглашению имя метода должно начинаться с On и сопровождаться названием события. Производный класс может не вызывать базовую реализацию метода в переопределении. Будьте готовы к этому, не включая в базовый метод код который требуется для корректной работы базового класса.

ИСПОЛЬЗУЙТЕ один параметр для передачи аргументов события. Параметр должен быть назван e и должен иметь тип класса аргументов события.

ИЗБЕГАЙТЕ передачи null в качестве параметра отправителя при возникновении нестатического события. Но используйте null при возникновении статического события.

ИЗБЕГАЙТЕ передачи null в качестве параметра аргументов события. Следует передавать EventArgs.Empty, если вы не хотите передавать какие-либо данные в метод обработки событий. Разработчики ожидают, что этот параметр не будет null.

⚠️ РАССМОТРИТЕ вызов событий, которые конечный пользователь может отменить. Это относится только к пред-событиями. Используйте System.ComponentModel.CancelEventArgs или его подкласс в качестве аргумента события, чтобы позволить конечному пользователю отменять события.



Пользовательские обработчики событий

Есть случаи, когда EventHandler<T> не может использоваться, например, когда инфраструктура должна работать с более ранними версиями CLR, которые не поддерживают обобщения. В таких случаях вам может потребоваться спроектировать и разработать пользовательский делегат обработчика событий.

ИСПОЛЬЗУЙТЕ void как тип результата для событий. Обработчик событий может вызывать несколько методов обработки событий, возможно, для нескольких объектов. Если бы методы обработки событий могли возвращать значение, для каждого вызова события было бы несколько возвращаемых значений.

ИСПОЛЬЗУЙТЕ object в качестве типа первого параметра обработчика события и называйте его sender.

ИСПОЛЬЗУЙТЕ System.EventArgs или его подкласс в качестве типа второго параметра обработчика событий и называйте его e.

ИЗБЕГАЙТЕ добавления более двух параметров в обработчик события.



Продолжение следует…



Источник: https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/