我有一个静态类,它暴露了一个事件:
public static class MyStaticClass
{
static bool myBool= false;
public static bool MyBool
{
get { return myBool; }
private set
{
myBool= value;
var handler = MyBoolChanged;
if (handler != null)
handler(null, null);
}
}
public static event EventHandler MyBoolChanged;
}
然后我使用这种模式注册它:
class AnotherClass
{
WeakReference _me;
public MyMethodInAnotherClass()
{
_me = new WeakReference(this);
MyStaticClass.MyBoolChanged+=
(_me.Target as AnotherClass).MyMethodInAnotherClassCallback;
}
private void MyMethodInAnotherClassCallback(some arguments)
{
}
}
我想要实现的是MyStaticClass
只会在AnotherClass
的实例尚未被处理(并且尚未注销)的情况下才执行处理程序。
答案 0 :(得分:2)
我可以看到使用它的最好方法是忘记一个事件,而是使用某种列表;让我们说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,并删除所有死亡的fooo。
然后您只需要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);
}
}