Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > .NET для новичков > Указатели на функции(делегаты) - смысл?


Автор: Gunslinger 25.8.2010, 12:49
Похоже я не программист - смотрю мсдн и не могу понять их смысл. Сама оболочка вроде понятна - чтобы было видно, к какому участку памяти, зачем обращаемся и что получаем. А сам смыл указателя непонятен. Нельзя в качестве параметра передать метод. Наверное, техническая причина, но зачем передавать сам метод, когда можно передать объект, его содержащий, а затем уже его вызвать?

В с++ указатели на методы еще понять могу: нужно обратиться к функции в dll, которая висит в памяти. 

Автор: ДобренькийПапаша 25.8.2010, 13:29
Цитата(Gunslinger @  25.8.2010,  12:49 Найти цитируемый пост)
Нельзя в качестве параметра передать метод.

С помощью делегата можно! smile

Цитата(Gunslinger @  25.8.2010,  12:49 Найти цитируемый пост)
зачем передавать сам метод, когда можно передать объект, его содержащий, а затем уже его вызвать?


Ну уж хотя бы потому, что при инициализации объекта вы затратите чёрт знает (разработчик знает) сколько памяти. А при вызове через делегат - расход только на делегат.
Енто раз.

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

Енто два.

С помощью делегатов можно делать последовательность вызовов функций (поскольку к делегату можно прицепить не одну функцию).

Енто три.

Если вы разрабатываете код, который будет кем-то унаследован и дорабатываем, то когда вы предоставляете какой-то функционал, вы не знаете как его конкретно захочет использовать тот, кто будет использовать ваш код.

Енто четыре.

Например, возьмём LINQ.

Берём любой int массив обыкновенный (System.Array)

Код

int[] a = {3,1,5,4,2,7,4,3};

IEnumerable b = a.Where(n=>n>2); //b содержит все числа из массива а, которые больше двух


Функция Where принимает делегат Predicate(здесь я написал лямбда-выражение).
Благодаря делегатам пользовать массива может делать что хочет, задавать какие хочешь функции для работы с массивом, чтобы вернуть то, что надо.

Автор: mrbrooks 25.8.2010, 13:59
Цитата(Gunslinger @  25.8.2010,  13:49 Найти цитируемый пост)
Наверное, техническая причина, но зачем передавать сам метод, когда можно передать объект, его содержащий, а затем уже его вызвать?

интересно - а каким ты образом реализуешь события на такой архитектуре? smile

ничего ацкого в делегатах нет. как ты уже и говорил - делегаты это просто указатели на функции( только типобезопасные), т.е. это как callback функции в С++. 

Цитата(Gunslinger @  25.8.2010,  13:49 Найти цитируемый пост)
В с++ указатели на методы еще понять могу: нужно обратиться к функции в dll, которая висит в памяти.  

ха! посмотри тот же STL. Да там все алгоритмы реализованы с предикатами. А это и есть ни что иное, как указатели на функции.

Так что по аналогии с С++ все симметрично + безопасность + дополнительный функционал объекта папы-делегата (см. док)

Добавлено через 2 минуты и 6 секунд
в общем твоя проблема не в делегатах - а в смысле функций обратного вызова - как таковых smile 

Автор: Gunslinger 25.8.2010, 18:12
Цитата(mrbrooks @  25.8.2010,  13:59 Найти цитируемый пост)
в общем твоя проблема не в делегатах - а в смысле функций обратного вызова - как таковых

Почитал вики с гуглом. Сформулировал вопрос: причина введения в язык указателей на функции (как их называют "обратного вызова") -- технические или архитектурные? Из-за специфики железа (связанные со стеком или еще чем) или из-за плюшек с той же событийной модели? Читаю и не могу выделить основную причину.

Автор: ДобренькийПапаша 25.8.2010, 19:48
Сейчас основная причина - архитектурная. Событийная модель издатель-подписчик это комильфо!  ИМХО smile 

Автор: mrbrooks 26.8.2010, 07:46
Цитата(Gunslinger @  25.8.2010,  19:12 Найти цитируемый пост)
архитектурные? 

да

Цитата(Gunslinger @  25.8.2010,  19:12 Найти цитируемый пост)
из-за плюшек с той же событийной модели?

да.


Автор: Gunslinger 30.8.2010, 10:20
Мсдн, интуит, гугл, книги.. Щас каша в голове. Архитектурно мой мозг имеет такая схема:
1. Объект-отправитель - класс с event-полями, которые на самом деле не поля, а классы.
2. Объект-получатель - класс, где есть метод(ы) для активации по событию. 
Связь. Где что пишут, даже не знаю, что правильно. Варианты, какие прочитал:
1. В объект-получатель передать ссылку на объект-отправитель, вызвать его event-поле и присвоить метод-обработчик.
2. 
Код

public Forml() 

    InitializeComponent (); 
    buttonOne.Click += new EventHandler(Button_Click); 


Либо это "обложка" для программиста и на самом деле компилятор "развернет" его по варианту 1. Т.е. в нечто вроде этого:
Код

public delegate void EventHandler();

public class Forml() 

    private Button buttonOne;
    public Forml(Button buttonOne){ 
             buttonOne.Click += EventHandler(Button_Click);
    }; 
    public void Button_Click() { Console.WriteLine("Button clicked"); };



либо есть несколько способов подписаться на событие.

Автор: KelTron 30.8.2010, 10:42
Возьми Троелсена и почитай главу про делегаты и события, там всё очень хорошо разъясняется. Твои вопросы отпадут сами собой..

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)