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;
}
...
...
}