C# 在使用自定义委托时,检查事件处理程序是否有订户

C# 在使用自定义委托时,检查事件处理程序是否有订户,c#,events,delegates,C#,Events,Delegates,所以这个想法很简单,我如何检查是否有重复的订户 所以基本上如果我有 _moduleEvent+=\u coachesEvents.OnDefficultyScoreListChanged 多次订阅 位置,我不希望该方法调用两次(或更多) 我当前的代码(研究后添加了逻辑): // ///指向多模块方法的委托 /// /// /// 私有委托void ModuleEventHandler(对象发送方,OpportunityEventArgs args args); /// /// ///

所以这个想法很简单,我如何检查是否有重复的订户

所以基本上如果我有

_moduleEvent+=\u coachesEvents.OnDefficultyScoreListChanged

多次订阅 位置,我不希望该方法调用两次(或更多)

我当前的代码(研究后添加了逻辑):

//
///指向多模块方法的委托
/// 
/// 
/// 
私有委托void ModuleEventHandler(对象发送方,OpportunityEventArgs args args);
/// 
/// 
/// 
私有事件模块eventhandler\u模块event
{
添加
{
如果(_moduleEvent==null | |!_moduleEvent.GetInvocationList()包含(值))
{
_moduleEvent+=值;
}
}
去除
{
_moduleEvent-=值;
}
}
如果我检查它是否为null并检查GetInNotificationList,我会得到一个错误,即_moduleEvent应该出现在+=等的左侧

        /// <summary>
        /// Check whether there are any subscribers
        /// </summary>
        private void _onModuleEvent(BusinessEntities.Opportunity o)
        {
            if (_moduleEvent != null)
                _moduleEvent(this, new OpportunityEventArgs() { Opportunity = o });
        }
//
///检查是否有订户
/// 
private void\u onModuleEvent(BusinessEntities.Opportunity o)
{
if(_moduleEvent!=null)
_moduleEvent(这是新的OpportunityEventArgs(){Opportunity=o});
}
我还看到_moduleEvent应该出现在上面+=error的左侧

我只能假设这与自定义委托有关?如果我在eventHandler中删除add/remove,显然一切都正常


非常感谢您的帮助。

我建议您创建字典并检查一下

创建类,如下所示

public class Subscription
{
  public readonly MethodInfo MethodInfo;
  public readonly WeakReference TargetObjet;

  public Subscription(Action<Tmessage> action, EventAggregator eventAggregator)
  {
      MethodInfo = action.Method;
      TargetObjet = new WeakReference(action.Target);
  }
}
公共类订阅
{
公共只读MethodInfo MethodInfo;
公共只读WeakReference TargetObjet;
公共订阅(操作、事件聚合器、事件聚合器)
{
MethodInfo=action.Method;
TargetObjet=新的WeakReference(action.Target);
}
}
而不是在暴露事件的类中使用该类

Public class EventExposer
{
  private Dictionary<Type, IList> subscriber;

  public EventExposer()
  {
            subscriber = new Dictionary<Type, IList>();
  }

   public void AddEvent(Action action)
   {
            Type t = typeof(action.Target);
            if (!subscriber.ContainsKey(t))
            {
                    subscriber.Add(t, action);
            }
   }

}
公共类事件曝光器
{
专用词典订户;
公共事件曝光器()
{
订户=新字典();
}
公共无效事件(行动)
{
类型t=类型of(action.Target);
如果(!subscriber.ContainsKey(t))
{
添加(t,action);
}
}
}

@PanagiotisKanavos是的,我一直在编程,却不知道。关于主题的更多信息,OP,你能不能在添加处理程序之前无条件地删除它?@Asad实际上是在2008年添加的。它们很少用于边缘情况,例如从两个具有相同事件名称的接口继承,我可以这样做,但没有详细介绍系统。这将是一个相当大和重大的事件。所以本质上会有系统事件和模块事件。理想情况下,我正在寻找一种干净、健壮的方法来实现这一点。我对事件做了更多的研究,您的代码似乎有问题。您需要有一个私有的“backing”事件(有点像backing字段),它的定义类似于so
private event ModuleEventHandler\u moduleEvent,句号。然后,您可以添加一个
公共事件
,该事件为该私有事件提供访问器,但不能自行引发。例如,您可以执行
公共事件模块eventhandler ModuleEvent{add{{u ModuleEvent+=value;}删除{{u ModuleEvent-=value;}}
。您可以对
\u moduleEvent
进行引发和空检查,但对于
moduleEvent
@TezWingfield,您不能执行这两项操作。请在此处查看代码:。它认为这就是你想要它做的。
Public class EventExposer
{
  private Dictionary<Type, IList> subscriber;

  public EventExposer()
  {
            subscriber = new Dictionary<Type, IList>();
  }

   public void AddEvent(Action action)
   {
            Type t = typeof(action.Target);
            if (!subscriber.ContainsKey(t))
            {
                    subscriber.Add(t, action);
            }
   }

}