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


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.