弱点参考-我做得对吗
本文关键字:参考 弱点 | 更新日期: 2023-09-27 18:25:19
我有一个静态类,它公开了一个事件:
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
的实例尚未释放(并且尚未注销)的情况下执行处理程序。
我能看到的最好的使用方法是忘记一个事件,而是使用某种列表;比方说CCD_ 3;然后你可以有:
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,并删除所有剩余的死foo。
然后您只需要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);
}
}