Как узнать, какие объекты слушают мое событие? - PullRequest
0 голосов
/ 28 октября 2009

У меня есть класс с событием:

public event MyEventHandler MyEvent;

Есть ли способ получить указатель на коллекцию объектов (отражением или иным образом), которые прослушивают это событие?

РЕДАКТИРОВАТЬ - Хм, простите, чтобы переместить стойки ворот - мне нужно , чтобы иметь возможность сделать это с помощью отражения найти слушателей. Я не вижу очевидного способа доступа к свойству GetInvocationList с помощью отражения ...

Спасибо!

Ответы [ 2 ]

4 голосов
/ 28 октября 2009
List<object> targets = MyEvent.GetInvocationList().Select(d => d.Target).ToList();

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

public event EventHandler MyEvent;

...

MyEvent(this, EventArgs.Empty);

Является синтаксическим сахаром. Что это на самом деле делает:

private EventHandler compilerGeneratedName;

public event EventHandler MyEvent
{
    add { compilerGeneratedName += value; }
    remove { compilerGeneratedName -= value; }
}

...

compilerGeneratedName(this, EventArgs.Empty);

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

Нет прямого способа связать внешнюю выставленную конструкцию event с обработчиком поддержки, кроме как с прямым способом связать property с резервной переменной: именно потому, что не обязательно отношения один-к-одному . Очень вероятно, что есть, но, как правило, так не должно быть.

Вы можете попробовать использовать отражение, чтобы проверить закрытые переменные, которые имеют правильный тип EventHandler<> в типе, который объявляет событие (обратите внимание, что вам придется сделать это в конкретном типе , который объявляет событие, , а не в подклассе) и проверяет, можете ли вы определить какую-либо корреляцию с именами, но это в лучшем случае ненадежное решение.

0 голосов
/ 28 октября 2009
MulticastDelegate.GetInvocationList()
...