Кращий спосіб оголошення подій


14

Я досить задоволений своїм розумінням моделі подій .NET. Я думаю, що я можу нерозуміти невеликий нюанс системи.

Коли я почав виставляти події на свої заняття, я застосував би такий стандартний спосіб:

public event EventHandler<MyEventArgs> MyEvent;

Це означало, що для кожного, хто підписався на подію, потрібен такий метод, як:

void HandleThatEvent(object sender, MyEventArgs args){...}

Що приємно, але я виявив, що рідко дбаю про відправника, тому він зробив багато підписів методів роздутою.

Тому я перейшов до оголошення власних типів делегата

public delegate void MyEventHandler(SomeClass argument);

Що скоротило безлад, але залишило у мене невелику проблему, коли справа стосувалася написання обробників:

eventImplmentor.MyEvent += HandleThatEvent;
.
.
.
void HandleThatEvent(/*oh, um, what arguments does it take? Intellisense isn't telling me*/)

Тож мені доведеться повернутися до декларації делегата і подивитися, а потім повернутися назад і записати їх, або скласти його і чекати, коли їм скажуть.

Так що тепер замість цього, я просто використовувати Action, Action<T>або будь-який інший шаблон припадки.

public event Action<SomeClass> MyEvent;

Так що я можу навести курсор на подію і сказати, які параметри її очікують.

Зрештою, моє запитання: чи є найкраща практика для оголошення подій у C #? Чи варто повертатися до EventHandler<T>шляху, або це Action<T>прийнятно?


Не забудьте переконатися, що обробник локально скопійований на місце, де ви запускаєте подію, завжди бажайте зробити це для безпеки потоку.
— Снуп

Ви можете писати власні розумні, середні та худі події, безпечні для типу, у інкапсульований код, але все, що ви публікуєте, повинно відповідати стандартній схемі, інакше це просто заплутає користувачів вашого класу (і, мабуть, також деякі інструменти).
— Мартін Мейт

Відповіді:


8

Для простого, внутрішнього управління подіями, є такі, які просто використовуються Actionабо Action<T>, як ви пропонуєте. Я схильний використовувати стандартну схему, включаючи Відправника, навіть для внутрішніх подій, тому що ніколи не знаєш, коли згодом ти можеш викрити клас чи подію, і я не хотів би, щоб покарання було переробляти метод події просто для того, щоб зробити це загальнодоступне.

Я погоджуюсь з вами, що підпис обробки подій трохи важчий, ніж це має бути для простих сценаріїв, але він добре розроблений для обробки поступової міграції, оскільки з часом можуть стати необхідними додаткові аргументи події. В цілому, я б дотримувався стандартного шаблону, тим більше, що, як ви зазначали, ви отримуєте належну підтримку IntelliSense лише в цьому випадку.

Для чого це варто, я поклав трохи часу на це і придумав іншу схему обробки подій : Підпис події в .NET - Використання сильно набраного "Відправника"? . Метою тут було не видалити відправника, а зробити його загалом сильним набраним, TSenderа не слабко набраним System.Object. Це працює дуже добре; однак, ви втрачаєте підтримку IntelliSense, коли ви це робите, тому є нещасний компроміс.

Загалом я б дотримувався стандартного шаблону, але цікаво подумати про потенційно кращі способи цього зробити.


Дякуємо, що вказали мені на ваше запитання. Це дуже цікаво. Я досі не розумію, чому це так важливо, щоб відправник був обов'язковим. Більшу частину часу я не хвилююся про відправника. Це лише якесь довільне правило MS?
— Метт Еллен

Ні, звичайно, ви можете оголосити своїх делегатів, як завгодно. Політика .NET завжди включає відправника, і це не зовсім погана ідея.
— Ніл

@Neil: Я розумію, що він іноді корисний, але я не знаю політики завжди робити це, тим більше, що MS рекомендують робити події своїм шляхом. Одне з речей, які мені дуже подобаються у подіях, - це вміння відокремлювати заняття. Якщо я включаю об'єкт, то він буде знову з'єднаний. Якщо це лише відповідність вимогам CLS, я можу з цим жити.
— Метт Еллен

З’єднується резервна копія знову, лише якщо ви використовуєте об'єкт відправника, інакше не має значення, що ставиться як значення відправника, оскільки ви не використовуєте його. Залежність існує лише в тому випадку, якщо вам потрібна залежність. Я бачу, звідки ви приїжджаєте, і якби відправник об'єкта зник з усіх кодів з будь-якого сервера на планеті, я не затримався б ночами.
— Ніл

Так, ви можете надіслати "null" як відправника, якщо дійсно хочете ... Але, включивши Відправника, сам обробник подій міг скасувати підписку, якщо цього захоче. Однак у цілому я б сказав, що знати джерело події, як правило, досить важливо.
— Майк Розенблум
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.