Мне было интересно, стоит ли использовать слабые события (где они подходят), используя что-то вроде следующего (грубое доказательство кода концепции):
class Foo {
private WeakEvent<EventArgs> _explodedEvent = new WeakEvent<EventArgs>();
public event WeakEvent<EventArgs>.EventHandler Exploded {
add { _explodedEvent += value; }
remove { _explodedEvent -= value; }
}
private void OnExploded() {
_explodedEvent.Invoke(this, EventArgs.Empty);
}
public void Explode() {
OnExploded();
}
}
Разрешить другим классам подписываться и отписываться от событий с более традиционным синтаксисом С#, а под капотом фактически реализуются со слабыми ссылками:
static void Main(string[] args) {
var foo = new Foo();
foo.Exploded += (sender, e) => Console.WriteLine("Exploded!");
foo.Explode();
foo.Explode();
foo.Explode();
Console.ReadKey();
}
Где вспомогательный класс WeakEvent<TEventArgs>
определяется следующим образом:
public class WeakEvent<TEventArgs> where TEventArgs : EventArgs {
public delegate void EventHandler(object sender, TEventArgs e);
private List<WeakReference> _handlers = new List<WeakReference>();
public void Invoke(object sender, TEventArgs e) {
foreach (var handler in _handlers)
((EventHandler)handler.Target).Invoke(sender, e);
}
public static WeakEvent<TEventArgs> operator + (WeakEvent<TEventArgs> e, EventHandler handler) {
e._handlers.Add(new WeakReference(handler));
return e;
}
public static WeakEvent<TEventArgs> operator - (WeakEvent<TEventArgs> e, EventHandler handler) {
e._handlers.RemoveAll(x => (EventHandler)x.Target == handler);
return e;
}
}
Это хороший подход? есть ли какие-либо нежелательные побочные эффекты для этого подхода?