![]() |
|
Модераторы: Partizan, gambit |
![]()
|
|
| Medved |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 7209 Регистрация: 15.9.2002 Где: Kazakhstan, Astan a Репутация: 3 Всего: 154 |
Объясните мне пожалуйста принцип работы функций обратного вызова.
-------------------- |
|||
|
||||
| Domestic Cat |
|
||||||||||||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5452 Регистрация: 3.5.2004 Где: Dallas, US Репутация: 9 Всего: 172 |
Полный код
//(код не проверял) 1. Объявляется делегат:
2. Объявляется метод с той же сигнатурой, что и делегат, т.е. с тем же возвращаемым значением и аргументами
3. Создается объекта класса, который содержит нужный метод
4. Создается сам объект-делегат, которому передается ссылка на метод
5. Вызывается делегат
Делегат - это по сути дела класс, наследющий от Delegate\ При создании делегата ему передается ссылка на метод (то же самое что и в С, но "безопасное", т.е. ссылку на метод "самому" пользовать нельзя, только через делегат). Можно передавать ссылку на статик метод, или инстанс метод, как в данном случае. Главное чтоб сигнатура совпадала. При этом генерируется класс, содержащий ссылку на данный метод, плюс ряд вспомогательных методов, для асинхронного вызова и т п; и далее создается объект этого класса (myDelegate). У данного объекта есть метод DynamicInvoke(), который вызывает переданный делегату метод. Для упрощения этот метод можно вызывать просто myDelegate(/*аргументы*/). Например, то же самое, что и в примере, можно было бы сделать так
Сокращение позволяет рассматривать объект делегат как "метод", т.е. вызывать delegate("Hello, World"). Делегаты можно комбинировать, класс делегата может хранить ссылки на любое число методов, главное чтобы сигнатуры были одинаковы:
В данном случае делегат будет вызван 4 раза, толку с этого нет (здесь), но во многих случаях это нужно. Например, если несколько объектов заинтегесованы в оповещении при наступлении некого события, плюс нужно в процессе работы изменять список этих объектов. -------------------- |
||||||||||||||||
|
|||||||||||||||||
| Medved |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 7209 Регистрация: 15.9.2002 Где: Kazakhstan, Astan a Репутация: 3 Всего: 154 |
thx.
-------------------- |
|||
|
||||
| Medved |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 7209 Регистрация: 15.9.2002 Где: Kazakhstan, Astan a Репутация: 3 Всего: 154 |
Вообще если честно, то меня интересует сам принцип. Т.е. как разработчики .NET обеспечили возможность использования делегатов. Как это рабоает на самом низком уровне.
-------------------- |
|||
|
||||
| Дрон |
|
||||||
![]() Java-ненавистник :) ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 3179 Регистрация: 29.12.2002 Где: Санкт-Петербург Репутация: 24 Всего: 93 |
Только Гейтс это знает Хотя, можно предположить, что примерно так:
Для не public методов нужно ещё учесть это
И т.п. -------------------- Да. Именно так. |
||||||
|
|||||||
| Medved |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 7209 Регистрация: 15.9.2002 Где: Kazakhstan, Astan a Репутация: 3 Всего: 154 |
Хорошо, задам вопрос по другому.
Я пишу свой компилятор и разработал для него свой язык. Хочу, чтобы программисты, которые будут писать на этом языке, могли определять и использовать события, говоря по другому callback function. Как мне это реализовать? Может кто-нибудь объяснить теорию? -------------------- |
|||
|
||||
| Дрон |
|
|||
![]() Java-ненавистник :) ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 3179 Регистрация: 29.12.2002 Где: Санкт-Петербург Репутация: 24 Всего: 93 |
Pegas
Странный вопрос. Для реализации этого в Си используются указатели на функции. В C# - рефлекшн. С точки зрения компилятора Си, в переменную просто сохраняется адрес в памяти, по которому находится нужная функция, в С# сохраняется какая-то информация из метаданных. Я, похоже, просто не понимаю в чём проблема. Это сообщение отредактировал(а) Дрон - 4.7.2005, 17:43 -------------------- Да. Именно так. |
|||
|
||||
| Medved |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 7209 Регистрация: 15.9.2002 Где: Kazakhstan, Astan a Репутация: 3 Всего: 154 |
В каком формате? -------------------- |
|||
|
||||
| Дрон |
|
|||
![]() Java-ненавистник :) ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 3179 Регистрация: 29.12.2002 Где: Санкт-Петербург Репутация: 24 Всего: 93 |
В Си это просто 32-битное число -- адрес
Ну и на этапе компиляции ещё сверяется соответствие типов данных (возвращаемое значение и параметры) В C# если заглянуть в делегат, то видно, что есть поле Method - информация о вызываемом методе и Target - информация об объекте, которому принадлежит данный метод (я в примере такую штуку и реализовал без использоваия делегата). Хотя на самом деле, делегат вещь более сложная, т.к. может хранить в себе инфу о многих разных методах. Кстати, до C# точно такая же штука была в C++ Builder и называлась closure. Вот. Добавлено @ 18:21 Дрон Конкретная реализация хранения ссылки на метод в C# от нас скрыта. Либо там хранится какой-то внутренний указатель (число). Что вероятно, но вызывает сомнения. Либо там хранится просто описание вроде "ConsoleApplication1.Class1.SomeMethod", которого достаточно благодаря метаданным. Это сообщение отредактировал(а) Дрон - 4.7.2005, 18:21 -------------------- Да. Именно так. |
|||
|
||||
| Дрон |
|
|||
![]() Java-ненавистник :) ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 3179 Регистрация: 29.12.2002 Где: Санкт-Петербург Репутация: 24 Всего: 93 |
Вот что пишет MSDN
-------------------- Да. Именно так. |
|||
|
||||
| Medved |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 7209 Регистрация: 15.9.2002 Где: Kazakhstan, Astan a Репутация: 3 Всего: 154 |
Спасибо.
-------------------- |
|||
|
||||
![]()
|
| Прежде чем создать тему, посмотрите сюда: | |
|
|
Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов. Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :) Так же не забывайте отмечать свой вопрос решенным, если он таковым является :) Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |