2
public sealed class WeakEvent<TDelegate>
{
public event TDelegate OnEvent;
...
...
}
我剛剛創建我的自定義WeakEventHandler,我想它包裝在一個WeakEvent類是否有可能創建一個具有泛型事件的類?
和林不知道,如果它是一個好主意,有
private HashSet<TDelegate> _eventHandlerList = new HashSet<TDelegate>();
和手動調用的所有方法。
如果你想看到的WeakEventHandler:
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;
}
}
這可能嗎?顯然,是的。你真正的問題是什麼? – 2014-10-29 17:03:42
好行:公共事件TDelegate OnEvent;不編譯!那麼解決方法是什麼? – elios264 2014-10-29 17:11:35
爲什麼不使用'EventHandler'和'WeakEvenHandler 其中TArgs:EventArgs' –
juharr
2014-10-29 17:24:22