Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.69/13: Рейтинг темы: голосов - 13, средняя оценка - 4.69
 Аватар для limeniye
1182 / 624 / 160
Регистрация: 19.04.2018
Сообщений: 2,923

Именование делегатов и событий

12.04.2022, 21:26. Показов 3128. Ответов 11
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Есть такая приставка для делегатов как EventArgs. Иногда используют что-то типо ActionHandler.

Вот я хотел бы понять как правильно именовать делегаты.

Как я понял, EventArgs используется в том случае, если указывается sender. Или как?

C#
1
public delegate void StudentsChangedEventArgs(object sender, Student student);
C#
1
2
3
4
public interface IStudentsService
{
    event StudentsChangedEventArgs StudentsChanged;
}
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
12.04.2022, 21:26
Ответы с готовыми решениями:

Именование экземпляром делегатов
Почему в примере в док максфт экземпляр строго типизированного делегата именуется в стиле паскаль? public static Action<string>...

Получения событий без делегатов
Как получить события в C# Console Application без использования делегатов?

Применение делегатов в качестве обработчиков событий
Реализовать собственное событие (имитация) нажатие клавиш мыши или клавиатуры. Разработать событием на основе стандартного события и...

11
2393 / 1922 / 763
Регистрация: 27.07.2012
Сообщений: 5,562
13.04.2022, 00:05
Цитата Сообщение от limeniye Посмотреть сообщение
Есть такая приставка для делегатов как EventArgs. Иногда используют что-то типо ActionHandler.
Нет такой приставки. Args как бы явно намекает на какие-то аргументы. Обработчики событий обычно именуются как Чего-нибудьHandler. А EventArgs это вообще конкретный тип.
C#
1
delegate void SomeEventHandler(object sender, EventArgs e) { /* ... */ }
2
 Аватар для limeniye
1182 / 624 / 160
Регистрация: 19.04.2018
Сообщений: 2,923
13.04.2022, 00:17  [ТС]
John Prick, а чем отличается обработчик событий от конкретного типа?

А в каких случаях лучше использовать именно EventArgs тип, а в каких делегаты?
0
2393 / 1922 / 763
Регистрация: 27.07.2012
Сообщений: 5,562
13.04.2022, 00:24
Цитата Сообщение от limeniye Посмотреть сообщение
а чем отличается обработчик событий от конкретного типа?
Как яблоко от ботинка. Обработчик события - это некоторая функция, в общем случае. Тип - это тип.
Цитата Сообщение от limeniye Посмотреть сообщение
А в каких случаях лучше использовать именно EventArgs тип, а в каких делегаты?
Это не взаимозаменяемые вещи. EventArgs всего лишь тип для агрумента функции-обработчика. Делегат - способ задать эту функцию. EventArgs используется в разных обработчиках библиотечных функций, типа нажатия кнопки и т.п. Там его и надо использовать, другого и не получится. В своих обработчиках используйте то, что нужно исходя из логики программы.
1
 Аватар для limeniye
1182 / 624 / 160
Регистрация: 19.04.2018
Сообщений: 2,923
13.04.2022, 01:28  [ТС]
John Prick, тут не совсем понимаю саму суть.
Вот я могу в метод делегата передать всё что угодно. Хоть целый паровоз чисел. А могу сделать отдельный тип, унаследовать его от EventArgs и передать в качестве параметра.

Почему яблоко, а не ботинок?
0
2393 / 1922 / 763
Регистрация: 27.07.2012
Сообщений: 5,562
13.04.2022, 10:07
Цитата Сообщение от limeniye Посмотреть сообщение
Вот я могу в метод делегата передать всё что угодно. Хоть целый паровоз чисел. А могу сделать отдельный тип, унаследовать его от EventArgs и передать в качестве параметра.
Ну вот уже лучше. "В делегат передать объект EventArgs", а не "в каких случаях использовать EventArgs, а в каких делегат".

Да, если создаётся свой собственный делегат, то в него можно передавать всё, что угодно, что требуеся по сути задачи. Надо паровоз чисел - передаём этот паровоз, надо строки - передаём их; любой другой объект ничем от этого не отличается, в том числе и объект типа EventArgs. Если вам в своей задаче удобнее и логичнее использовать EventArgs или его наследников - используйте их.

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

Чуть примера:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// так определяется общепринятый библиотечный делегат для событий
// его не надо определять самому
delegate void EventHandler(object sender, EventArgs e);
 
class Button
{
    // ...
    public event EventHandler Click;
    // ...
}
 
// ваш класс. Тут "свобода слова", пишем то, что считаем нужным
delegate void StudentHandler(Student student, string what, object param);
 
class Student
{
    public string Name
    {
        get { return name; }
        set
        {
            name = value;
            if (Changed != null)
                Changed(this, "Name", name);
        }
    }
    
    public int Rating
    {
        get { return rating; }
        set
        {
            rating = value;
            if (Changed != null)
                Changed(this, "Rating", rating);
        }
    }
    
    public event StudentHandler Changed;
    
    private string name;
    private int rating;
}
2
 Аватар для limeniye
1182 / 624 / 160
Регистрация: 19.04.2018
Сообщений: 2,923
13.04.2022, 10:29  [ТС]
John Prick, не совсем тот ответ, которого я ожидаю услышать.
Сам смысл: для чего он нужен -- я так и не понял.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16133 / 11257 / 2888
Регистрация: 21.04.2018
Сообщений: 33,092
Записей в блоге: 2
13.04.2022, 11:14
Цитата Сообщение от limeniye Посмотреть сообщение
Есть такая приставка для делегатов как EventArgs
Это не приставка для делегатов.
Это рекомендованный базовый тип аргумента для делегата используемого для создания события.
Пример RoutedEvent - у него аргумент RoutedEventArgs производный от EventArgs.
Рекомендованные делегаты - это EventHandler и EventHandler<T>.
Для первого аргументом может быть только EventArgs, для второго - любой тип, но рекомендуется чтобы был производный от EventArgs.

Цитата Сообщение от limeniye Посмотреть сообщение
Иногда используют что-то типо Action
Постфикс Handler используется в именах делегатов безотносительно того будут ли они использованы для объявления события или нет.

Цитата Сообщение от limeniye Посмотреть сообщение
Как я понял, EventArgs используется в том случае, если указывается sender. Или как?
При создании события экземпляра, источник события обязательно должен быть одним из параметров события.
Экземпляров может быть много, а метод обработчик будет для них один.
И он как-то должен различать какой-конкретно экземпляр вызвал событие.

EventArgs используется когда у события нет параметра кроме самого источника.
Производные от EventArgs используются когда все параметры события (кроме источника) собираются в один общий объект.
Если у события несколько параметров (кроме источника), то EventArgs обычно не используется.

Цитата Сообщение от limeniye Посмотреть сообщение
чем отличается обработчик событий от конкретного типа?
Тип - это класс, структура, делегат, перечисление и т.д.
Обработчик (слушатель) - это метод, который является членом класса или структуры.

Цитата Сообщение от limeniye Посмотреть сообщение
А в каких случаях лучше использовать именно EventArgs тип, а в каких делегаты?
Вроде ответил выше, но ещё раз.
EventArgs - это базовый класс.
Он сам или производный от него класс может быть параметром делегата, но ни как не использоваться вместо делегата.
Делегат - это сигнатура допустимого метода.
EventArgs - тип параметра метода.
Но параметр не может же использоваться вместо метода.

Добавлено через 13 минут
Цитата Сообщение от limeniye Посмотреть сообщение
Вот я могу в метод делегата передать всё что угодно. Хоть целый паровоз чисел. А могу сделать отдельный тип, унаследовать его от EventArgs и передать в качестве параметра.
Есть свои плюсы и минусы у обоих подходов.
Если вы делаете событие "для себя", то можете объявить, например, такой делегат:
C#
1
2
3
delegate void PropertyChangedHandler(object sender, string propertyName, object oldValue, object newValue);
 
event PropertyChangedHandler PropertyChanged;
Но для извещения об изменения свойства уже есть событие, которое все используют INoifyPropertyChanged.PropertyChanged.
И введение своего события запутает всех кто будет использовать ваш тип.

Как быть?

Можно расширить аргумент события:
C#
1
2
3
4
5
class ExtPropertyChangedEventArgs : PropertyChangedEventArgs
{
    public object OldValue {get;}
    public object NewValue {get;}
}
Теперь вам не нужно создавать нового события.
Вы можете передать все данные через стандартный PropertyChanged, но с вашим типом аргумента.
Стандартные слушатели будут получать базовый PropertyChangedEventArgs и работать с ним как всегда.
Расширенные (продвинутые) слушатели будут приводить аргумент к типу ExtPropertyChangedEventArgs и получать из него дополнительные данные.
1
 Аватар для limeniye
1182 / 624 / 160
Регистрация: 19.04.2018
Сообщений: 2,923
13.04.2022, 11:47  [ТС]
Элд Хасп, резюмирую: если делегат может усложниться -- лучше сделать отдельный тип для параметра унаследованный от EventArgs. Если пользователь решит сделать делегату "апргейт" -- ему нужно будет расширить класс указанный в параметре старого делегата и создать новый делегат с ним.

Как я понимаю, это в дальнейшем может в каких-то местах упростить код, так как один тип подобен другому.

Есть ли какие-то примеры, которые наглядно показывают удобство применения подобного рода подхода?
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16133 / 11257 / 2888
Регистрация: 21.04.2018
Сообщений: 33,092
Записей в блоге: 2
13.04.2022, 12:04
Цитата Сообщение от limeniye Посмотреть сообщение
Есть ли какие-то примеры, которые наглядно показывают удобство применения подобного рода подхода?
Я же выше дал пример с доп. данными для PropertyChanged.
Этот пример из реальной реализации.
Возможно даже на Форум загружал её - надо поискать.

Цитата Сообщение от limeniye Посмотреть сообщение
резюмирую: если делегат может усложниться -- лучше сделать отдельный тип для параметра унаследованный от EventArgs.
Даже не в этом дело.
Если вы создаёте абсолютно новый свой тип, то вам его нужно хорошо документировать.
Использование же .Net типа позволяет создать понятный всем код без излишнего документирования.
1
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
13.04.2022, 14:32
Лучший ответ Сообщение было отмечено limeniye как решение

Решение

Цитата Сообщение от limeniye Посмотреть сообщение
Есть ли какие-то примеры, которые наглядно показывают удобство применения подобного рода подхода?
Главное "удобство" такого подхода — цеплять один и тот же обработчик на любое событие, вне зависимости от конкретного типа аргумента.
Полезно, если надо знать, что что-то случилось, но абсолютно не нужно знать что именно.
2
13.04.2022, 16:16  [ТС]

Не по теме:

kolorotur, я ждал именно этого ответа. Спасибо.

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
13.04.2022, 16:16
Помогаю со студенческими работами здесь

Применение делегатов в качестве обработчиков событий
Реализовать собственное событие (имитация) нажатие клавиш мыши или клавиатуры. Разработать событием на основе стандартного события и...

Написать код с использованием событий и делегатов
Подскажите, как правильно реализовать следующую задачу: Есть класс Man: public class Man { public Man(string...

Использование делегатов и событий при смене поля "телефон" объекта
У меня есть некий класс Person, где есть такие поля, как &quot;Имя&quot;, &quot;Фамилия&quot;, &quot;Телефон&quot;. Также в другом классе Database есть методы, которые...

Игра "Такси" с использованием делегатов и событий
Суть задачи: Используя делегаты и события написать игру по следующему сценарию: Игра «Такси». Два круга начинают движение слева к центру...

Разработка делегатов, событий, анонимных методов
1) Объявить делегат. 2) Реализовать функции ввода и вывода элементов одномерного массива. 3) Реализовать функцию замены всех...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 11.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru