是否可以使用泛型事件创建类


public sealed class WeakEvent<TDelegate>
{
        public event TDelegate OnEvent;
     ...
     ...
}

我刚刚创建了我的自定义 WeakEventHandler,我想把它包装在一个 WeakEvent 类中

我不确定这是否是一个好主意

    private HashSet<TDelegate> _eventHandlerList = new HashSet<TDelegate>();

并手动调用所有方法。

如果你想看到弱事件处理程序:

  public sealed class WeakEventHandler2<TDelegate>
    {
        private readonly WeakReference _targetRef;
        private readonly Action<WeakEventHandler2<TDelegate>> _unsubscriber;
        private readonly TDelegate _realHandler;
        private readonly MethodInfo _subscriberMethodInfo;
        static WeakEventHandler2()
        {
            if (!typeof(TDelegate).IsSubclassOf(typeof(Delegate)))
                throw new InvalidOperationException(typeof(TDelegate).Name + " is not a delegate type");
        }
        public WeakEventHandler2(TDelegate subscriber, Action<WeakEventHandler2<TDelegate>> unsubscriber)
        {
            var handler = (subscriber as Delegate);
            if (handler == null)
            {
                throw  new InvalidOperationException("subscriber is not a Delegate");
            }
            _unsubscriber = unsubscriber;
            _targetRef = new WeakReference(handler.Target);
            _subscriberMethodInfo = handler.Method;
            //Delegate Parameters
            ParameterExpression[] parameters =
                _subscriberMethodInfo.GetParameters()
                    .Select(parameter => Expression.Parameter(parameter.ParameterType, parameter.Name))
                    .ToArray();
            //Target instance ( holded by the weak reference
            ParameterExpression target = Expression.Parameter(typeof(object), "target");
            //call to the subscriber on a specific  target instance
            LambdaExpression methodCall  =
                Expression.Lambda(
                    Expression.Call(Expression.Convert(target, handler.Target.GetType()), handler.Method, parameters),
                    new[] {target}.Concat(parameters));
            //Expression of weakreference target
            Expression<Func<object>> instanceExpr = () => _targetRef.Target;
            //Expression of unsubscribing call
            Expression<Action> unsubscriberExpr = () => _unsubscriber(this);
            ParameterExpression tExp = Expression.Variable(typeof (object),"instanceVarContainer");
            BinaryExpression assignement = Expression.Assign(tExp, Expression.Invoke(instanceExpr));
            ConditionalExpression body = Expression.IfThenElse(Expression.NotEqual(tExp, Expression.Constant(null, typeof (object))),
                Expression.Invoke(methodCall, new[] { tExp }.Concat(parameters)), Expression.Invoke(unsubscriberExpr));
            //call to the subscriber with unsubscription in case the weakreference is not alive
            _realHandler = Expression.Lambda<TDelegate>(Expression.Block(new[] { tExp }, assignement, body), parameters).Compile();
        }
        public static implicit operator TDelegate(WeakEventHandler2<TDelegate> weh)
        {
            return weh._realHandler;
        }

    }

好吧,如果有人想知道,它会是这样的:

 public class WeakEvent2<TDelegate> where TDelegate : class
 {
        private TDelegate _invocationList;
         public TDelegate Invoke
        {
            get { return _invocationList;    }
        }

        public void Subscribe(TDelegate handler)
        {
            lock (this)
                _invocationList = Delegate.Combine(_invocationList as Delegate, new WeakEventHandler2(handler, weh=> Unsubscribe(weh) )) as TDelegate;
        }
        ...
        ...
}

相关内容

  • 没有找到相关文章

最新更新