gpt4 book ai didi

c# - 是否可以创建具有通用事件的类?

转载 作者:太空宇宙 更新时间:2023-11-03 15:49:11 27 4
gpt4 key购买 nike

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


}

最佳答案

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

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

...
...
}

关于c# - 是否可以创建具有通用事件的类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26636285/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com