2014-10-29 122 views
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; 
     } 


    } 
+0

這可能嗎?顯然,是的。你真正的問題是什麼? – 2014-10-29 17:03:42

+0

好行:公共事件TDelegate OnEvent;不編譯!那麼解決方法是什麼? – elios264 2014-10-29 17:11:35

+2

爲什麼不使用'EventHandler '和'WeakEvenHandler 其中TArgs:EventArgs' – juharr 2014-10-29 17:24:22

回答

0

那麼如果有人想知道,這將是這樣的:

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

     ... 
     ... 
} 
相關問題