Есть ли способ узнать, был ли обработчик события добавлен к объекту? Я сериализую список объектов в / из состояния сеанса, чтобы мы могли использовать состояние сеанса на основе SQL ... Когда у объекта в списке изменилось свойство, его необходимо пометить, о чем должным образом заботился обработчик события , Однако теперь, когда объекты десериализованы, они не получают обработчик событий.
В приступе легкого раздражения я просто добавил обработчик событий в свойство Get, которое обращается к объекту. Он вызывается сейчас, и это здорово, за исключением того, что он вызывается примерно 5 раз, поэтому я думаю, что обработчик просто добавляется каждый раз, когда к объекту обращаются.
Это достаточно безопасно, чтобы просто игнорировать, но я бы предпочел сделать это намного чище, проверив, добавлен ли обработчик, поэтому я делаю это только один раз.
Это возможно?
РЕДАКТИРОВАТЬ: я не обязательно имею полный контроль над тем, какие обработчики событий добавляются, поэтому просто проверка на ноль не достаточно хорошо.
Ответы:
За пределами определяющего класса, как упоминает @Telos, вы можете использовать EventHandler только в левой части a
+=
или a-=
. Итак, если у вас есть возможность изменить определяющий класс, вы можете предоставить метод для выполнения проверки, проверив, является ли обработчик событияnull
- если да, то обработчик события не был добавлен. Если нет, то, возможно, и вы можете просмотреть значения в Delegate.GetInvocationList . Если один равен делегату, который вы хотите добавить в качестве обработчика события, то вы знаете, что он есть.И это можно легко изменить, чтобы он стал «добавить обработчик, если его там нет». Если у вас нет доступа к внутренностям класса, который выставляет событие, вам, возможно, придется изучить
-=
и+=
, как предлагает @Lou Franco.Тем не менее, вам может быть лучше пересмотреть способ ввода в эксплуатацию и вывода из эксплуатации этих объектов, чтобы увидеть, если вы не можете найти способ отслеживать эту информацию самостоятельно.
источник
Delegate.Equals(objA, objB)
если вы хотите проверить наличие точно такого же делегата. В противном случае сравнить свойства индивидуально, какif(objA.Method.Name == objB.Method.Name && objA.Target.GetType().FullName == objB.Target.GetType().FullName)
.Недавно я попал в похожую ситуацию, когда мне нужно было зарегистрировать обработчик для события только один раз. Я обнаружил, что вы можете сначала безопасно отменить регистрацию, а затем снова зарегистрироваться, даже если обработчик вообще не зарегистрирован:
Обратите внимание, что выполнение этого каждый раз при регистрации вашего обработчика гарантирует, что ваш обработчик будет зарегистрирован только один раз. Похоже, очень хорошая практика для меня :)
источник
Если это единственный обработчик, вы можете проверить, является ли событие пустым, если нет, обработчик был добавлен.
Я думаю, что вы можете смело вызывать - = для события с вашим обработчиком, даже если оно не добавлено (если нет, вы можете его перехватить) - чтобы убедиться, что его там нет, прежде чем добавлять.
источник
В этом примере показано, как использовать метод GetInvocationList () для получения делегатов для всех обработчиков, которые были добавлены. Если вы хотите посмотреть, был ли добавлен определенный обработчик (функция), вы можете использовать массив.
Вы можете проверить различные свойства в свойстве Method делегата, чтобы увидеть, была ли добавлена определенная функция.
Если вы хотите посмотреть, подключен ли он только один, вы можете просто проверить на ноль.
источник
Если я правильно понимаю вашу проблему, у вас могут быть большие проблемы. Вы сказали, что другие объекты могут подписаться на эти события. Когда объект сериализуется и десериализуется, другие объекты (те, которыми вы не управляете) теряют свои обработчики событий.
Если вас это не беспокоит, тогда достаточно сохранить ссылку на ваш обработчик событий. Если вы беспокоитесь о побочных эффектах других объектов, теряющих свои обработчики событий, вы можете пересмотреть свою стратегию кэширования.
источник
Я согласен с ответом Альфа, но мало что можно изменить, это использовать,
источник
Единственный способ, который сработал для меня, - это создание логической переменной, которую я установил в true, когда добавляю событие. Затем я спрашиваю: если переменная ложна, я добавляю событие.
Эта переменная может быть глобальной.
источник
источник