Лучший способ использовать это - забыть о событии и использовать вместо него какой-то список;скажем List<WeakReference>
;тогда вы можете получить:
interface IFoo {
void Bar(some args);
}
с:
static class Whatever {
private static readonly List<WeakReference> items=new List<WeakReference>();
public static void Add(IFoo foo) {
if(foo != null) {
var newRef = new WeakReference(foo);
lock(items) { items.Add(newRef); }
}
}
public static void DoIt(some args) {
lock(items) {
foreach(var item in items) {
IFoo foo = item.IsAlive ? item.Target as IFoo : null;
if(foo != null) foo.Bar(some args);
}
}
}
}
с дополнительными механизмами для удаления определенного IFoo и удаления всех мертвых foos, оставленных todo.
Тогдавам просто нужен AnotherClass : IFoo
с реализацией Bar()
, которая применяет ваш обратный вызов.
Дополнительный акцент: статические коллекции (включая события) довольно опасны;Вы должны время от времени проводить какую-то проверку, чтобы удалить пустые элементы, и попытаться отменить подписку, где это возможно (например, в Dispose()
).Как иллюстрация:
public static void Remove(IFoo foo) {
lock (items) { // also remove any dead debris
items.RemoveAll(x => !x.IsAlive || x.Target == foo || x.Target == null);
}
}