![]() |
Модераторы: Partizan, gambit |
![]() ![]() ![]() |
|
Dims |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1016 Регистрация: 21.11.2006 Репутация: 0 Всего: 11 |
Объясните попроще, как работать с событиями?
Вот в джаве всё просто: если отправитель события, а есть получатель. Если получатель хочет знать о наступлении события, то он регистрирует у отправителя. Всё. Два участника. Ещё может быть в виде отдельного класса заведено событие. Тогда будет три участника, причём все осмысленны: 1) отправитель 2) получатель 3) событие А что у нас в Си#? Вот, например, читаю тут: http://msdn.microsoft.com/en-us/library/9aackb16(VS.85).aspx Простая ситуация, будильник звенит и кого-то будет. В Джаве было бы максимум три класса: будильник, спящий человек и звонок. А тут: AlarmEventArgs - это, наверное, отображение звонка AlarmEventHandler - что отображается? AlarmClock - это будильник WakeMeUp - что это? А, понял, это спящий человек... Пока отбой ![]() Хотя нафига ещё делегат заводить... Добавлено через 9 минут и 46 секунд А вот, такой вопрос. Допустим, я хочу как-то говорить, что данный класс у меня будет реагировать на некие события. В Джаве я создавал интерфейс получателя событий и делал, чтобы класс его имплементил. А тут что? И можно ли как-то создать интерфейс или что-то типа того, чтобы указывать, что класс будет отправителем событий? В Джаве этого сделать нельзя. Там надо просто по договорённости определить методы Add-чего-то-там-Listener и тогда, если такой метод в классе есть, то значит, класс является отправителем соответствующих событий. А как тут? |
|||
|
||||
PashaPash |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1233 Регистрация: 3.1.2008 Репутация: 13 Всего: 49 |
Тут точно так же, но есть ньюансы ![]() |
|||
|
||||
QryStaL |
|
|||
![]() Intellectual feast ![]() ![]() Профиль Группа: Участник Сообщений: 914 Регистрация: 30.11.2005 Репутация: 14 Всего: 32 |
Dims, здесь очень хорошо подойдет паттерн Observer из GoF
Делегат выступает в качестве Observer, event в качестве Subject. Соответственно ConcreteObserver - класс, в котором описывается метод с сигнатурой, соответствующей делегату, ConcreteSubject - класс, содержащий event Это сообщение отредактировал(а) QryStaL - 25.10.2008, 22:22 Присоединённый файл ( Кол-во скачиваний: 18 ) ![]() -------------------- I don't need a reason being who I am... |
|||
|
||||
Dims |
|
||||||||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1016 Регистрация: 21.11.2006 Репутация: 0 Всего: 11 |
А этот "Обзёрвер" чем-то отличается от того, что я описал словами?
PashaPash, а как мне сделать интерфейс, который бы был отправителем? Я хочу определить тип, который бы мог содержаться в графическом элементе управления и который бы автоматически перерисовывался бы. Ну уровне классов, вроде, понятно: 1) надо определить делегата:
2) внутри класса надо определить событие
3) потом определить функцию
и 4) вызывать эту функцию после каждого обновления. Кстати, сама по себе необходимость определять 3 сущности кажется мне странной. Ну а как это сделать на уровне интерфейса? когда я в интерфейсе написал
оно мне стало говорить, что 'Test.Etalon' does not implement interface member 'Test.IDarkness.Redraw' Etalon -- это класс, который реализует интерфейс. Что я должен определить в этом классе (и нафига)? |
||||||||
|
|||||||||
PashaPash |
|
||||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1233 Регистрация: 3.1.2008 Репутация: 13 Всего: 49 |
Dims, интерфейс - это буквально список того, что должно быть реализовано в классе. Строчка "event RedrawHandler Redraw;" в интерфейсе означает только что реализующие его классы должны объявить event с типом обработчика RedrawHandler и именем Redraw. Т.е. что все классы с этим интерфейсом должны реализовать add_Redraw и remove_Redraw.
Класс должен эти методы реализовать. Фишка в том, что точно такая же строчка строчка в классе превращается в метаданные и стандартную реализацию евента:
Можно реализовать их вручную, например, хранить делегаты событий не как поля, а как записи в hashtable. |
||||
|
|||||
VK_Techno |
|
|||
Новичок Профиль Группа: Участник Сообщений: 10 Регистрация: 29.9.2007 Репутация: нет Всего: нет |
Для реализации эвента из интерфейса достаточно его public-объявления в классе, реализующем этот интерфейс. Дополнительные методы (типа add_Event() и другие) - лишь следование гайдлайнам от MS.
|
|||
|
||||
Dims |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1016 Регистрация: 21.11.2006 Репутация: 0 Всего: 11 |
||||
|
||||
PashaPash |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1233 Регистрация: 3.1.2008 Репутация: 13 Всего: 49 |
Это зависит не от следования гайдлайнам, а от используемого компилятора/VES. Компилятор C# в .NET добавляет в интерфейс функции add/remove, и их обязательно придется реализовать в классе. Хотя бы в виде public event, для которого тот же компилятор сгенерирует стандартную реализацию add/remove.
Мне кажется что для исправления какой-т другой ошибки надо как-то по-другому подправить код. |
|||
|
||||
Dims |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1016 Регистрация: 21.11.2006 Репутация: 0 Всего: 11 |
Вот тогда вопросы по коду из доки:
1) можно ли было делегат объявить так public delegate void SampleEventHandler(Publisher sender, int arg1, int arg2); Казалось бы, это логичнее. Поскольку источником данных событий может быть только данный класс, то и тип параметра sender должен быть таким. Поскольку параметры события предопределены, проще явно описать их набор и типы, а не заворачивать в дополнительный класс SampleEventArgs 2) зачем определять функцию RaiseSampleEvent, разве Publisher не сможет запускать события просто при помощи команды SampleEvent(this, 1, 2, 3) Или наследники не смогут этого делать даже несмотря на то, что событие объявлено public? 3) не надо ли было внутри RaiseSampleEvent проверить SampleEvent на null? Что будет, если никто не подписан на событие, а будет вызван метод RaiseSampleEvent? |
|||
|
||||
QryStaL |
|
||||
![]() Intellectual feast ![]() ![]() Профиль Группа: Участник Сообщений: 914 Регистрация: 30.11.2005 Репутация: 14 Всего: 32 |
Во-первых, метод RaiseSampleEvent описан неправильно, должно быть так
Во-вторых public являются только методы AddHandler и RemoveHandler; поле, содержащее экземпляр делегата, является private. Поэтому наследники смогут вызвать событие только через RaiseSampleEvent.
NullReferenceException -------------------- I don't need a reason being who I am... |
||||
|
|||||
Rififi |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1254 Регистрация: 9.3.2008 Репутация: 5 Всего: 36 |
Dims,
1) можно ли было делегат объявить так public delegate void SampleEventHandler(Publisher sender, int arg1, int arg2); Можно, но MS рекомендует определять параметры через наследование от EventArgs PS. вместо проверки на null, можно подписаться на "заглушку" SampleEvent += delegate {}; |
|||
|
||||
Dims |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1016 Регистрация: 21.11.2006 Репутация: 0 Всего: 11 |
||||
|
||||
QryStaL |
|
|||
![]() Intellectual feast ![]() ![]() Профиль Группа: Участник Сообщений: 914 Регистрация: 30.11.2005 Репутация: 14 Всего: 32 |
как раз += и -= соответствуют AddHandler и RemoveHandler инкапсуляция -------------------- I don't need a reason being who I am... |
|||
|
||||
Dims |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1016 Регистрация: 21.11.2006 Репутация: 0 Всего: 11 |
||||
|
||||
PashaPash |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1233 Регистрация: 3.1.2008 Репутация: 13 Всего: 49 |
||||
|
||||
![]() ![]() ![]() |
Прежде чем создать тему, посмотрите сюда: | |
|
Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов. Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :) Так же не забывайте отмечать свой вопрос решенным, если он таковым является :) Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |