[C#] 弱委托,支持+=和-=写法

复制代码
class ClassA
{
    public void Print1()
    {
        Console.WriteLine("111");
    }
    public void Print2()
    {
        Console.WriteLine("222");
    }
    public void Print3()
    {
        Console.WriteLine("333");
    }
}
复制代码
复制代码
private static WeakDelegate<Action> weak;

static void Main(string[] args)
{
    Test();

    var a = new ClassA();
    weak += a.Print2;
    weak += a.Print3;
    weak -= a.Print3;

    GC.Collect();
    GC.WaitForPendingFinalizers();

    var target = weak.Target;
    target?.Invoke();

    Console.WriteLine("End");
    Console.ReadLine();
}

private static void Test()
{
    weak += new ClassA().Print1;
}
复制代码

输出:

222
End

复制代码
class WeakDelegate<T> where T : Delegate
{
    #region Static Method

    public static WeakDelegate<T> operator +(WeakDelegate<T> weakDelegate, T t)
    {
        if (t == null)
            return weakDelegate;

        var ret = new WeakDelegate<T>(t);

        if (weakDelegate != null)
            ret._tuples.InsertRange(0, weakDelegate._tuples);

        return ret;
    }

    public static WeakDelegate<T> operator -(WeakDelegate<T> weakDelegate, T t)
    {
        if (t == null)
            return weakDelegate;

        var ret = new WeakDelegate<T>(null);

        if (weakDelegate != null)
        {
            foreach (var tuple in weakDelegate._tuples)
            {
                var weak = tuple.Item1;
                var method = tuple.Item2;

                if (!method.IsStatic && !weak.IsAlive)
                    continue;

                if (weak.Target == t.Target && method == t.GetMethodInfo())
                    continue;

                ret._tuples.Add(tuple);
            }
        }

        return ret;
    }

    #endregion

    public WeakDelegate(T t)
    {
        _delegateType = typeof(T);
        _tuples = new List<Tuple<WeakReference, MethodInfo>>();

        if (t != null)
        {
            var weak = new WeakReference(t.Target);
            var method = t.GetMethodInfo();

            _tuples.Add(new Tuple<WeakReference, MethodInfo>(weak, method));
        }
    }

    public bool IsAlive => _tuples.Any(q => q.Item1.IsAlive);

    public T Target
    {
        get
        {
            var delegates = new List<Delegate>(_tuples.Count);

            foreach (var tuple in _tuples)
            {
                var weak = tuple.Item1;
                var method = tuple.Item2;

                if (method.IsStatic)
                    delegates.Add(method.CreateDelegate(_delegateType, null));

                var target = weak.Target;

                if (target != null)
                    delegates.Add(method.CreateDelegate(_delegateType, target));
            }

            return delegates.Count == 0 ? null : (T)Delegate.Combine(delegates.ToArray());
        }
    }

    private List<Tuple<WeakReference, MethodInfo>> _tuples;
    private Type _delegateType;
}
View Code
复制代码

 

posted @   孤独成派  阅读(179)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
点击右上角即可分享
微信分享提示