• [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
  • 相关阅读:
    打包应用和构建Docker镜像(docker在windows上)
    Docker 在Windows上的安装
    Docker Zero Deployment and Secrets (二)
    Docker Zero Deployment and Secrets (一)
    系统基础信息模块psutil之获取系统性能篇
    IPython的安装方法
    用三种方法设置CentOS7使用代理服务器上网
    CentOS7修改pypi源
    CentOS7升级Python3
    CPU频率的简单测试工具
  • 原文地址:https://www.cnblogs.com/pumbaa/p/16196159.html
Copyright © 2020-2023  润新知