Тут ведь получается, что нужно хранить этот 'MyHandler' только для того, чтобы отписаться от события.
Т.е. его нельзя сделать анонимной функцией, локальной переменной и т.д.
Эти мысли привели к более разумному применению как например в Rx, где подписка возвращает объект через который можно отписаться.
_NN>Тут ведь получается, что нужно хранить этот 'MyHandler' только для того, чтобы отписаться от события. _NN>Т.е. его нельзя сделать анонимной функцией, локальной переменной и т.д.
Не нужно ничего хранить, это глобальная константа. На ивент же может быть больше одного листенера...
_NN>>Тут ведь получается, что нужно хранить этот 'MyHandler' только для того, чтобы отписаться от события. _NN>>Т.е. его нельзя сделать анонимной функцией, локальной переменной и т.д.
KAR>Не нужно ничего хранить, это глобальная константа. На ивент же может быть больше одного листенера...
Как не нужно ?
Вот в этом примере как отписаться ?
window.addEventListener('click', function() {} );
Вот классическая ошибка первого варианта в JavaScript:
function f() {
var handler = function() {
}
// Удалить старое если было
window.removeEventListener('click', f);
// Добавить новое
window.addEventListener('click', f);
}
Тут каждый вызов функции создается другая переменная и в итоге ничего не удаляется.
Второй вариант также позволяет иметь более одного подписчика.
_NN>>>Тут ведь получается, что нужно хранить этот 'MyHandler' только для того, чтобы отписаться от события. _NN>>>Т.е. его нельзя сделать анонимной функцией, локальной переменной и т.д.
KAR>>Не нужно ничего хранить, это глобальная константа. На ивент же может быть больше одного листенера... _NN>Как не нужно ? _NN>Вот в этом примере как отписаться ? _NN>
Здравствуйте, _NN_, Вы писали:
_NN>Кто же все таки посчитал, что первый подход лучше ?
Я никогда не слышал, чтобы при дизайне C# 1.0 рассматривались другие варианты (анонимных функций тогда не было). Так что вполне возможно, что никто не решал, что выбранный подход лучше, это могло быть единственное решение, которое тогда пришло в голову дизайнерам. Хранить анонимные функции, конечно, неудобно, поэтому в Rx придумали другой подход. Но тебе всё равно нужно хранить объект, у которого ты собираешься вызывать Dispose() для отписки.
Здравствуйте, nikov, Вы писали:
N>Здравствуйте, _NN_, Вы писали:
_NN>>Кто же все таки посчитал, что первый подход лучше ?
N>Я никогда не слышал, чтобы при дизайне C# 1.0 рассматривались другие варианты (анонимных функций тогда не было). Так что вполне возможно, что никто не решал, что выбранный подход лучше, это могло быть единственное решение, которое тогда пришло в голову дизайнерам. Хранить анонимные функции, конечно, неудобно, поэтому в Rx придумали другой подход. Но тебе всё равно нужно хранить объект, у которого ты собираешься вызывать Dispose() для отписки.
В любом случае нужен какой-нибудь идентификатор для отписки.
Другое дело, что им почему-то является сам метод.
В таком варианте не всегда возможно подписаться в одном месте, а отписаться в другом.
Как единственное решение ? На WinAPI не смотрели что ли
Образный код:
auto timer = SetTimer(myCallback);
KillTimer(timer);
Здравствуйте, _NN_, Вы писали:
_NN>В любом случае нужен какой-нибудь идентификатор для отписки. _NN>Другое дело, что им почему-то является сам метод. _NN>В таком варианте не всегда возможно подписаться в одном месте, а отписаться в другом.
_NN>Как единственное решение ? На WinAPI не смотрели что ли _NN>Образный код: _NN>
_NN>Тут ведь получается, что нужно хранить этот 'MyHandler' только для того, чтобы отписаться от события. _NN>Т.е. его нельзя сделать анонимной функцией, локальной переменной и т.д.
_NN>Эти мысли привели к более разумному применению как например в Rx, где подписка возвращает объект через который можно отписаться. _NN>
наоборот сделать уже сложнее, поэтому лучше использовать +=/-= с которыми можно использовать обе схемы,
чем использовать Subscribe с которым уже не сделать -=.
Здравствуйте, Abyx, Вы писали:
A>наоборот сделать уже сложнее, поэтому лучше использовать +=/-= с которыми можно использовать обе схемы, A>чем использовать Subscribe с которым уже не сделать -=.
Что значит сложнее ?
Да и проблема то какая решается ?
subscription1 = event.Subscribe(func1)
subscription2 = event.Subscribe(func2)
subscription2.Dispose(); // Отписались от 2
subscription1.Dispose(); // Отписались от 1
Здравствуйте, _NN_, Вы писали:
_NN>Здравствуйте, Abyx, Вы писали:
A>>наоборот сделать уже сложнее, поэтому лучше использовать +=/-= с которыми можно использовать обе схемы, A>>чем использовать Subscribe с которым уже не сделать -=.
_NN>Что значит сложнее ? _NN>Да и проблема то какая решается ?
_NN>
_NN>subscription1 = event.Subscribe(func1)
_NN>subscription2 = event.Subscribe(func2)
_NN>subscription2.Dispose(); // Отписались от 2
_NN>subscription1.Dispose(); // Отписались от 1
_NN>
Здравствуйте, Abyx, Вы писали:
A>и кто и где должен хранить subscription?
Кто подписывается тот и хранит или передает дальше куда надо.
Разработчик волен делать что хочет.
С другой стороны не нужно знать про сам метод, чтобы подписаться.
Можно подписываясь передать приватный метод или анонимный, и отписаться можно извне без проблем.
_NN>как например в Rx
Погуглил и нашёл: Just say No to “Reactive Programming”.
Автор пишет, что это всего лишь Observer/Observable и был описан в книге GoF много лет тому назад.
Потому, наверное, так и сделано: "согласно положениям GoF".
Здравствуйте, os24ever, Вы писали:
_NN>>как например в Rx O>Погуглил и нашёл: Just say No to “Reactive Programming”. O>Автор пишет, что это всего лишь Observer/Observable и был описан в книге GoF много лет тому назад. O>Потому, наверное, так и сделано: "согласно положениям GoF".
Здравствуйте, _NN_, Вы писали: _NN>Можно подписываясь передать приватный метод или анонимный, и отписаться можно извне без проблем.
По-прежнему не очень понятно, в чём принципиальная разница между:
Здравствуйте, os24ever, Вы писали: O>Автор пишет, что это всего лишь Observer/Observable и был описан в книге GoF много лет тому назад. O>Потому, наверное, так и сделано: "согласно положениям GoF".
Автор — поверхностный хам и воинствующее невежество. Он нашёл в Rx знакомое слово и из этого раздул целую статью.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Удобнее тем, что внешнему коду не нужно знать конкретный тип обработчика, чтобы отменить операцию. Это значит, что мы можем использовать обобщённую логику отписки для разных "событий".
К тому же IDisposable можно комбинировать:
var disposable1 = stream.Subscribe(...);
var disposable2 = Disposable.Create(() => ...);
return new CompositeDisposable() { disposable1, disposable2 } //Возвращает IDisposable, который по очереди вызовет disposable1 и disposable2
Здравствуйте, ionoy, Вы писали:
I>Удобнее тем, что внешнему коду не нужно знать конкретный тип обработчика, чтобы отменить операцию.
Что такое "конкретный тип обработчика"?
I>Это значит, что мы можем использовать обобщённую логику отписки для разных "событий".
Пример кода, который вы хотите написать, в студию. С пояснением, почему вы не можете его написать в нынешнем коде.
I>К тому же IDisposable можно комбинировать:
I>var disposable1 = stream.Subscribe(...); I>var disposable2 = Disposable.Create(() => ...);
I>return new CompositeDisposable() { disposable1, disposable2 } //Возвращает IDisposable, который по очереди вызовет disposable1 и disposable2 I>[/c#]
Непонятно, почему именно Disposable.
Почему вы не хотите комбинировать, например, Action.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>Пример кода, который вы хотите написать, в студию. С пояснением, почему вы не можете его написать в нынешнем коде.
Встяну. Вот лично у меня присутствует чисто психологический дискомфорт сохранять где-либо для последующей отписки ссылку на функцию. Оно конечно это можно списать на фантомные боли императивщика, но — а вдруг это замыкание какое, к примеру, тянущее за собой чёрт знает сколько захваченных данных?