弱点参考-我做得对吗

本文关键字:参考 弱点 | 更新日期: 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);
    }
}