Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.78/18: Рейтинг темы: голосов - 18, средняя оценка - 4.78
 Аватар для Glitch
10 / 10 / 5
Регистрация: 28.09.2015
Сообщений: 139

Что такое событие, для чего оно нужно

28.01.2016, 12:19. Показов 3987. Ответов 28

Студворк — интернет-сервис помощи студентам
Помогите разобраться, что ли
Вчера пытался понять что же такое событие, для чего оно нужно, зачем ему делегат
Ну и собственно вот попытки

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
44
45
46
47
48
49
50
51
52
53
using System;
 
public delegate void MethodContainer(); // Это делегат, который вызовет метод с сигнатурой void
 
class ClassCounter // Это класс издатель
{
    public event MethodContainer onCount; // Это событие, которое произойдет при вызове onCount
 
    public void Count()
    {
        for (int i = 0; i < 100; i++)
        {
            if (i == 10)
            {
                Console.WriteLine("Событие вызвано");
                onCount(); // Вызов события 
            }
        }
    }
}
 
class Handler_I // Класс подписчик
{
    public void Message()
    {
        Console.WriteLine("Handler_I: Счет достиг 10");
    }
}
 
class Handler_II // Класс подписчик 
{
    public void Message()
    {
        Console.WriteLine("Handler_II: Счет достиг 10");
    }
}
 
class Program
{
    static void Main()
    {
        ClassCounter Counter = new ClassCounter(); // Создание экземпляров
        Handler_I Handler1 = new Handler_I();
        Handler_II Handler2 = new Handler_II();
 
        //Подписались на событие
        Counter.onCount += Handler1.Message;
        Counter.onCount += Handler2.Message;
 
        //Запустили счетчик
        Counter.Count();
    }
}
Как я понял, делегат нужен событию для того чтобы подписчики были только одной сигнатуры?
То есть нельзя чтобы, например, подписчики были типа int и типа void?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
28.01.2016, 12:19
Ответы с готовыми решениями:

Swapfile.sys Что это такое и для чего оно?
Я считаю что этот файл занимает много места. Реально ли удалить. Я знаю как уменьшить pagefile.sys(файл подкачки) но про swapfile ничего не...

Подскажите что такое md5 шифрование пароля и для чего оно надо ?
Подскажите что такое md5 шифрование пароля и для чего оно надо ?

Что такое md5? Для чего это нужно? Где используется?
Всем доброго времени суток! Что такое md5? Для чего это нужно? Где используется? Спасибо!

28
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
28.01.2016, 13:48
Цитата Сообщение от Glitch Посмотреть сообщение
Как я понял, делегат нужен событию для того чтобы подписчики были только одной сигнатуры?
Событие — это и есть экземпляр делегата, потому да — на событие могут подписываться только методы с такой же сигнатурой.

Цитата Сообщение от Glitch Посмотреть сообщение
То есть нельзя чтобы, например, подписчики были типа int и типа void?
Нет, хотя тип возвращаемого значения и не является частью сигнатуры метода.
0
TheGreatCornholio
 Аватар для Woldemar89
1255 / 733 / 285
Регистрация: 30.07.2015
Сообщений: 2,408
28.01.2016, 14:10
Вчера не слабо помучался с событиями.
На всякий случай, сообщу, что такой код не потокобезопасен,
нет проверки на null (а вдруг никто не подписался?),
а также желательно отписываться от событий (-=).

Лучше полностью почитать.
http://codeblog.jonskeet.uk/20... -with-c-6/
http://stackoverflow.com/quest... ead-safety
http://stackoverflow.com/quest... t-practice
0
 Аватар для Glitch
10 / 10 / 5
Регистрация: 28.09.2015
Сообщений: 139
28.01.2016, 14:22  [ТС]
Спасибо
А может ли быть у события несколько делегатов?
0
310 / 318 / 119
Регистрация: 29.10.2011
Сообщений: 1,006
28.01.2016, 14:29
Простым языком
Цитата Сообщение от Glitch Посмотреть сообщение
зачем ему делегат
Событие можно сказать основывается на делегате.

Делегат - это класс, который хранит в себе сигнатуру метода. Сигнатура метода - это тип возвращаемого значения и тип(ы) параметров (public string Foo (int a, bool b){}).
Экземпляр делегата может хранить в себе один и более методов (указателей на методы) с соответствующей ему сигнатурой.
События имеют больше семантическую разницу от делегатов. Философский смысл. По сути в событии создается поле типа нужного нам делегата, а также функции для добавления туда методов. События - некая "обертка" над делегатом.

Цитата Сообщение от Glitch Посмотреть сообщение
что же такое событие, для чего оно нужно,
Представьте вы разрабатываете игру (плевать на архитектуру и прочее).
У вас есть класс Game. У которого есть, например, функция Step - шаг персонажа на другую клетку, которая что-то возвращает, а может и нет - не суть). Программа работает, все отлично, вы ходите, собираете разные монетки. И, когда монеток n-е количество, побеждаете. Но вам хочется отображать статистику, например количество собранных монеток, чтоб при каждой взятой монетке у вас на экране счет увеличивался на 1 (например в лейбле lblScore).
Ваш класс Game вообще не в курсе ни о каком лейбле, он просто занимается своей задачей.
Для этого у вас есть делегат (названия нужно более обобщенные давать)
C#
1
delegate void deScoreChanged(int currentScore); //равноценно делегату Action<int>
И в классе гейм создаете событие ScoreChanged, которое мы вызываем после взятой монетки в функции Step (вызывать его желательнее не здесь, а там, где непосредственно обрабатывается взятие монетки, но для наглядности сойдет)
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Game
{
    public event deScoreChanged ScoreChanged;
 
    int score;
    //
    //    
    public void Step(int x, int y)
    {
        //
        //
        ScoreChanged(score); // вызываем, когда взяли монетку. если на событие не подписались выдаст эксепшн
    }
}
Теперь в коде, где мы работаем с экземпляром класса Game, в нашем случае в форме, подписываемся на это событие после создания экземпляра класса Game
C#
1
2
3
4
5
6
7
Game myGame = new Game();
myGame.ScoreChanged += GameScoreChanged;
 
void GameScoreChanged(int currentScore)
{
    lblScore.Text = currentScore.ToString();
}
и все, при каждом изменении состояния класса, которое относиться к счету измениться и значения лейбла.

Все контролы в ВинФорм содержат события, что бы сообщать пользователя о неких действиях.
Можно конечно использовать просто делегаты. И, например, в одном из свойств передавать делегат, который что-то там делает, но согласитесь, что так куда запутаннее: Передавать объекту ссылку на метод.. сигнализировать о неком события куда приятнее

пс. писал не в студии, может где-то печатался, но ведь в данном случае важна суть кода, а не грамотность)
2
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
28.01.2016, 14:35
Цитата Сообщение от sldp Посмотреть сообщение
Сигнатура метода - это тип возвращаемого значения и тип(ы) параметров
Строго говоря, тип возвращаемого значения сигнатурой метода не является, но в делегатах учитывается, да.

Правильней было бы сказать, что делегат — это класс, который хранит в себе сигнатуру метода, тип его возвращаемого значения и список ссылок на подписчиков и их подписанные методы.
1
TheGreatCornholio
 Аватар для Woldemar89
1255 / 733 / 285
Регистрация: 30.07.2015
Сообщений: 2,408
28.01.2016, 14:36
Цитата Сообщение от Glitch Посмотреть сообщение
А может ли быть у события несколько делегатов?
Цитата Сообщение от kolorotur Посмотреть сообщение
Событие — это и есть экземпляр делегата
На событие, как ты понял, можно подписаться много раз.
Можно в классе издателе определить несколько событий и вызывать каждое в зависимости от ситуации.

Или лучше оформлять события через EventHandler(object sender, EventArgs e) и передавать, что нужно, в EventArgs e.

Например можно подписаться на события нескольких экземпляров сервера, и при каждом событии на сервере,
параметры вызвавшего сервера будут передаваться в событие через аргументы.

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public delegate void ConnectedEventHandler(object sender, ConnectEventArgs e);
 
public class ConnectEventArgs
{
    Server server;
 
    public ConnectEventArgs(Server _server)
    {
      server = _server;
    }
    public string ServerName
    {
      get
      {
        return this.Server != null ? string.Empty : server.Name;
      }
    }
 
}
0
310 / 318 / 119
Регистрация: 29.10.2011
Сообщений: 1,006
28.01.2016, 15:09
kolorotur, хм.. выходит и название тоже относится к сигнатуре не знал. Ассоциировал всегда сигнатуру с неким шаблоном метода
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
28.01.2016, 15:18
Цитата Сообщение от sldp Посмотреть сообщение
выходит и название тоже относится к сигнатуре
Ну разумеется
Сигнатура метода — это то, что позволяет однозначно отличить один метод от другого.
0
 Аватар для Glitch
10 / 10 / 5
Регистрация: 28.09.2015
Сообщений: 139
28.01.2016, 15:19  [ТС]
Я вот чего еще не понимаю..
Допустим есть такой делегат, принимающий string в качестве параметра
C#
1
delegate string strMod(string str);
А тут
C#
1
2
3
4
5
6
7
8
9
10
11
public static void Main()
    {
        // Создание делегата.
        strMod strOp = new strMod(replaceSpaces); // ??????
        string str;
 
        // Вызываем методы посредством делегата.
        str = strOp("Это простой тест."); // В качестве параметра передается string
        Console.WriteLine("Результирующая строка: " + str);
        Console.WriteLine();
        //...
Как так выходит, что экземпляру делегата параметром передается МЕТОД, а потом уже string??
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
28.01.2016, 15:31
Цитата Сообщение от Glitch Посмотреть сообщение
Как так выходит, что экземпляру делегата параметром передается МЕТОД, а потом уже string??
Так для начала делегат надо создать — вот он там и создается, заодно ему передается ссылка на метод, который он будет запускать.
0
 Аватар для Glitch
10 / 10 / 5
Регистрация: 28.09.2015
Сообщений: 139
28.01.2016, 15:33  [ТС]
А смысл тогда в делегате, если мы сами назначаем какой метод ему запускать
Нельзя напрямую разве?
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
28.01.2016, 15:35
Цитата Сообщение от Glitch Посмотреть сообщение
А смысл тогда в делегате, если мы сами назначаем какой метод ему запускать
Нельзя напрямую разве?
Можно и напрямую, конечно.
А смысл в том, что сегодня мы знаем, а завтра мы уже не знаем.

Когда разработчик кнопки Button писал этот класс, знал ли он, какой метод вы захотите вызывать при клике на кнопку? Подозреваю, что не знал, потому предоставил вам делегат Click в виде события, которому вы можете передать ссылку на нужный вам метод, вызывающийся при клике на кнопку.
0
TheGreatCornholio
 Аватар для Woldemar89
1255 / 733 / 285
Регистрация: 30.07.2015
Сообщений: 2,408
28.01.2016, 18:16
Glitch, чтобы понять, просто считай, что событие - это обертка над списком делегатов.
+= добавит в список экземпляр делегата, -= удалит.
А при возникновении события, все добавленные экземпляры просто вызываются.
1
 Аватар для Glitch
10 / 10 / 5
Регистрация: 28.09.2015
Сообщений: 139
28.01.2016, 18:55  [ТС]
Цитата Сообщение от Woldemar89 Посмотреть сообщение
событие - это обертка над списком делегатов.
+= добавит в список экземпляр делегата, -= удалит.
А при возникновении события, все добавленные экземпляры просто вызываются.
Окей, я кажется разобрался
Теперь возник следующий вопрос:
Почему возникает ошибка когда я помещаю сам делегат в класс с событием?
0
TheGreatCornholio
 Аватар для Woldemar89
1255 / 733 / 285
Регистрация: 30.07.2015
Сообщений: 2,408
28.01.2016, 18:58
Цитата Сообщение от Glitch Посмотреть сообщение
Почему возникает ошибка
Где ошибка? Код продемонстрируйте.
0
 Аватар для Glitch
10 / 10 / 5
Регистрация: 28.09.2015
Сообщений: 139
28.01.2016, 19:03  [ТС]
C#
1
2
3
4
5
6
7
class MyEvent // Класс издатель
{
    // Объявляем делегат для события.
    delegate void MyEventHandler();
 
    public event MyEventHandler SomeEvent;
    //...
У меня делегат был вне класса, поместил его в класс и сразу две ошибки

Несогласованность по доступности: доступность типа события "MyEvent.MyEventHandler" ниже доступности события "MyEvent.SomeEvent"

Не удалось найти тип или имя пространства имен "MyEventHandler" (возможно, отсутствует директива using или ссылка на сборку).
0
TheGreatCornholio
 Аватар для Woldemar89
1255 / 733 / 285
Регистрация: 30.07.2015
Сообщений: 2,408
28.01.2016, 19:10
Цитата Сообщение от Glitch Посмотреть сообщение
У меня делегат был вне класса, поместил его в класс и сразу две ошибки
Зачем помещать его в класс? Сигнатура должна быть видна подписчикам, а вы ее прячете от них.
1
 Аватар для Glitch
10 / 10 / 5
Регистрация: 28.09.2015
Сообщений: 139
28.01.2016, 19:11  [ТС]
Цитата Сообщение от Woldemar89 Посмотреть сообщение
Сигнатура должна быть видна подписчикам
А, вот оно что
(вопрос не по теме) Как на сайте часовой пояс сменить? А то у меня GMT+4 вместо 2
0
TheGreatCornholio
 Аватар для Woldemar89
1255 / 733 / 285
Регистрация: 30.07.2015
Сообщений: 2,408
28.01.2016, 19:14
Цитата Сообщение от Glitch Посмотреть сообщение
Как на сайте часовой пояс сменить?
https://www.cyberforum.ru/prof... ditoptions
Опции даты и времени.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
28.01.2016, 19:14
Помогаю со студенческими работами здесь

Что такое eclipse и зачем оно нужно?
в общем для чего она нужна то кто в курсе я то скачал ее но там байда насчет одних проектов в каком месте там на яве програмировать и что...

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

OpenVZ, VMware® ESXi 64-bit - для чего оно нужно?
Извиняюсь, может не там создал тему, но не нашел более подходящего раздела. Объясните зачем нужно виртуализировать систему? Для чего это...

Правильно ли составлено выражение, и для чего оно нужно в данном коде?
Всем доброго времени суток! Нужно составить код для решения уравнения методом итераций 0.25х^3+x-1.2502=0 х Вопрос,...

Для чего нужно событие Form_QueryUnload
Добрый вечер объясните новичку что значит событие Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer) End Sub ...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Автозаполнение реквизитов при создании документа
Maks 26.03.2026
Код из решения ниже размещается в модуле объекта документа, в процедуре "ПриСозданииНаСервере". Автозаполнение реквизита Организации (тип Справочник. Организации): Если НЕ. . .
Команды "Заполнить" и "Очистить" на форме документа
Maks 26.03.2026
1. Команда формы "ЗаполнитьЗапчасти". На примере нетипового документа разработанного в конфигурации КА2. В качестве источника данных указан регистр накопления, в который записываются данные о. . .
Кому нужен AOT?
DevAlt 26.03.2026
Решил сделать простой ланчер Написал заготовку: dotnet new console --aot -o UrlHandler var items = args. Split(":"); var tag = items; var id = items; var executable = args;. . .
Отправка уведомления на почту при изменении наименования справочника
Maks 24.03.2026
Программная отправка письма электронной почты на примере изменения наименования типового справочника "Склады" в конфигурации БП3. Перед реализацией необходимо выполнить настройку системной учетной. . .
модель ЗдравоСохранения 5. Меньше увольнений- больше дохода!
anaschu 24.03.2026
Теперь система здравосохранения уменьшает количество увольнений. 9TO2GP2bpX4 a42b81fb172ffc12ca589c7898261ccb/ https:/ / rutube. ru/ video/ a42b81fb172ffc12ca589c7898261ccb/ Слева синяя линия -. . .
Midnight Chicago Blues
kumehtar 24.03.2026
Такой Midnight Chicago Blues, знаешь?. . Когда вечерние улицы становятся ночными, а ты не можешь уснуть. Ты идёшь в любимый старый бар, и бармен наливает тебе виски. Ты смотришь на пролетающие. . .
SDL3 для Desktop (MinGW): Вывод текста со шрифтом TTF с помощью библиотеки SDL3_ttf на Си и C++
8Observer8 24.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-text-sdl3-c. zip finish-text-sdl3-cpp. zip
Жизнь в неопределённости
kumehtar 23.03.2026
Жизнь — это постоянное существование в неопределённости. Например, даже если у тебя есть список дел, невозможно дойти до точки, где всё окончательно завершено и больше ничего не осталось. В принципе,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru