Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Обработка событий C#/Регистрация обратного вызова

Автор вопроса: Jeff DahmerОтветов: 4

События могут возвращать только void и получать объект sender/eventargs, верно?

Если это так, то craptastic.... как я могу передать указатель функции на другой объект, например:

public bool ACallBackFunc(int n)
{
    return n > 0;
}

public void RegisterCallback(Something s)
{
     s.GiveCallBack(this.ACallBackFunc);
}

Something::GiveCallBack(Action? funcPtr)

Я пытался использовать Action, но мне нужно, чтобы он возвращал какое-то значение, а Actions может возвращать только void. Кроме того, мы не знаем, какой обратный вызов мы получим; он может возвращать что угодно и иметь любые параметры! Я думаю, что рефлексию придется как-то использовать.

delegatescallback

Ответы

Ответ 1 · рейтинг 1 · yamspog

вам нужно создать делегата, который передает обратно интересующие вас классы

открытый делегат недействителен CallbackDelegate (что-то); публичное событие CallbackDelegate myCallback

public void myFunction() { if (myCallback!= null) myCallback(new something()); }

ознакомьтесь с руководством по msdn... http://msdn.microsoft.com/en-us/library/aa645739(VS.71).aspx

Ответ 2 · IAbstract

Я написал события, которые возвращают значение, обычно bool. Однако использование функции Func позволяет возвращать значения.

Ответ 3 · Fadrian Sudaman

Действие по определению не возвращает значение, вы можете использовать общую версию, которая допускает несколько параметров.

Если вы хотите, чтобы он возвращал значение, используйте Func или, если вы просто хотите, чтобы он возвращал логическое значение и принимал один аргумент, вы можете использовать Predicate

Или вы можете определить делегата так, как хотите, чтобы он возвращал void или значение и принимал любое количество аргументов. Вы можете определить делегата, как показано ниже, и это похоже на тип, который вы можете использовать. Затем вы можете передать его как параметр обратного вызова напрямую, без использования Action, Func или Predicate. Пользовательский делегат также часто используется при написании пользовательского обработчика событий многоадресной рассылки.

public delegate double PerformAverageEventHandler(int val1, int val2, int val3);

Ответ 4 · Kirk

Возможно, вы не понимаете, что событие является многоадресным делегатом, позволяющим нескольким слушателям события. Это оставит вас (потенциально) с необходимостью получать более одного возвращаемого значения.

Некоторые идеи, чтобы обойти это, состоят в том, чтобы передать ссылочный объект обработчику событий, сохраняющему ссылку на объект. Вы могли бы получить результат, но вам потребуется другое событие, чтобы узнать, когда объект был изменен. Но, вероятно, было бы лучше переосмыслить то, чего вы пытаетесь достичь. Это звучит как рецепт переполнения стека, когда вы попадаете в бесконечный цикл события, вызывающего изменение, которое затем вызывает событие.

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы