【问题标题】:event delegate (in)equality?事件委托(不)平等?
【发布时间】:2010-09-28 15:40:26
【问题描述】:

有人可以解释以下代码部分的含义吗:

private event UserChangedHandler m_UserChanged;
public event UserChangedHandler UserChanged
{
  add
  {
      if (m_UserChanged != value)
      {
        m_UserChanged += value;
      }
  }
}

谢谢

【问题讨论】:

    标签: c# events delegates operators inequality


    【解决方案1】:

    add { } 是一个类似于get { } 的属性构造,除了 add 对事件起作用。将委托添加到事件时,您在此处定义自定义功能。

    在这种情况下,此方法主体可防止连续重复(即您不能两次连续注册同一方法/处理程序)。

    所以在这个例子中:

    public void HandlerUserChanged(object o, UserChangedEventArgs args)
    {
         // some code
    }
    
    public void HandlerUserChanged2(object o, UserChangedEventArgs args)
    {
         // some code
    }
    

    稍后:

    UserChanged += HandleUserChanged;
    UserChanged += HandleUserChanged;
    UserChanged(this, new UserChangedEventArgs());
    

    HandleUserChanged 方法只会触发一次,即使您注册了两次。正常事件(没有add { })会调用该函数两次。

    但是:

    UserChanged += HandleUserChanged;
    UserChanged += HandleUserChanged2;
    UserChanged += HandleUserChanged;
    UserChanged(this, new UserChangedEventArgs());
    

    将允许HandleUserChanged 触发两次,因为最后注册的处理程序永远不会被添加。事件上的 == 运算符适用于 LAST 处理程序。 (感谢 Matthew 提请注意)

    【讨论】:

    • 虽然,上面的代码不会阻止你两次添加相同的方法。如果将方法 A 和方法 B 添加到 UserChanged 事件中,您仍然可以再次添加方法 A。
    • @Matthew Manela:你说得对,它只会阻止连续添加。还是一大早,谢谢你指出这一点。
    【解决方案2】:

    令我感到奇怪的是,m_UserChanged 被声明为一个事件,而不仅仅是一个委托实例(这是正确的术语吗……我对委托感到困惑)。事件类似于简单的属性模型,因为它们本质上将底层字段包装在一对透明方法中。

    按照我的理解,.Net 允许通过以下方式创建隐式(匿名?)事件和属性:

    public int Value { get; set;}
    public event EventHandler ValueChanged;
    

    然后创建相应的底层占位符对象以生成更像这样的东西:

    private int _Value;
    public int Value { get { return _Value;} set { _Value = value;}}
    
    private EventHandler _ValueChanged;
    public event EventHandler ValueChange { add { _ValueChanged += value;} remove { _ValueChanged -= value;}}
    

    当然可以显式定义底层对象,但是上面的代码示例看起来有点混淆显式和隐式事件声明......看起来下面实际上正在完成(在幕后,原来如此):

    private UserChangedHandler _m_UserChanged; 
    private event UserChangedHandler m_UserChanged { add { _m_UserChanged += value;} remove { _m_UserChanged -= value;}}
    public event UserChangedHandler UserChanged 
    { 
      add 
      { 
          if (m_UserChanged != value) 
          { 
            m_UserChanged += value; 
          } 
      } 
    } 
    

    我不猜,这在宏伟的计划中并不重要,但它看起来像是一个疏忽。

    【讨论】:

      猜你喜欢
      • 2010-12-10
      • 1970-01-01
      • 2013-01-18
      • 1970-01-01
      • 1970-01-01
      • 2015-08-02
      • 2019-05-16
      • 1970-01-01
      • 2013-10-23
      相关资源
      最近更新 更多