【问题标题】:How EventHandler += method is implemented?EventHandler += 方法是如何实现的?
【发布时间】:2018-01-28 20:45:38
【问题描述】:

我是 C# 的一日新手。让我们拥有

class C {
   // ...
   public event EventHandler Changed;
}

以后我们用它

cClassObject.Changed += new EventHandler(SomeOtherDelegate);

概念对我来说很清楚。

  • 在 Scala 等语言中的委托将是 FunctionN 类型,lambda。
  • 事件类似于 C# 中的对象级 pub-sub Observable 工具。

问题:

+= 运算符在哪里以及如何实现? 我找不到它的代码,它是那个类独有的特殊编译器吗?

谢谢

编辑: Here 是 Jon Skeet 的一些链接,用于深入 C# 设计(包括 Eric 建议的自己的博客)。

【问题讨论】:

    标签: c#


    【解决方案1】:

    它是该类独有的特殊编译器吗?

    这是一个特殊的编译器。不过,它不受EventHandler 的约束,而是一般的事件。您可以使用任何类型的委托声明事件。

    在幕后,它只是调用 Delegate.Combine 并进行一点同步来处理竞争条件:

    这段代码:

    public event EventHandler Test;
    
    public void Hello()
    {
        Test += Program_Test
    }
    

    会编译成:

    private EventHandler Test;
    
    public event EventHandler Test
    {
      add
      {
        EventHandler eventHandler = this.Test;
        EventHandler comparand;
        do
        {
          comparand = eventHandler;
          eventHandler = Interlocked.CompareExchange<EventHandler>(ref this.Test, (EventHandler) Delegate.Combine((Delegate) comparand, (Delegate) value), comparand);
        }
        while (eventHandler != comparand);
      }
      remove
      {
        EventHandler eventHandler = this.Test;
        EventHandler comparand;
        do
        {
          comparand = eventHandler;
          eventHandler = Interlocked.CompareExchange<EventHandler>(ref this.Test, (EventHandler) Delegate.Remove((Delegate) comparand, (Delegate) value), comparand);
        }
        while (eventHandler != comparand);
      }
    }
    

    【讨论】:

    • 是的。 Delegate.Combine 是一种静态方法,可以在任何类型的委托上调用。在幕后,它返回一种特殊的委托:MulticastDelegate (msdn.microsoft.com/en-us/library/…)
    • @Max:Combine不是传统意义上的作曲;通常我们将组合视为Func&lt;A, B&gt;Func&lt;B, C&gt; 组合成为Func&lt;A, C&gt;Combine 只是 sequential 组合:处理程序一个接一个地被调用。
    • @KevinGosse:请注意,C# 中的 所有 代表都是 MulticastDelegate。 C# 规范仅保证它们派生自Delegate,但实际上每个委托类型均派生自MulticastDelegate
    • @Max:我鼓励您获得一份The C# Programming Language 的纸质副本,其中包含我和其他 C# 专家的注释;您的许多问题可能都会在其中得到解答。
    • @Max:还可以考虑阅读我的旧 MSDN 博客、我的新博客,如果您对我们如何更改 C# 4 中的事件加法器代码生成特别感兴趣,请阅读 Chris 的博客:blogs.msdn.microsoft.com/cburrows/2010/03/04/…
    猜你喜欢
    • 1970-01-01
    • 2015-11-15
    • 2011-04-18
    • 1970-01-01
    • 2017-04-16
    • 2016-11-20
    • 2011-10-02
    • 2011-03-20
    • 1970-01-01
    相关资源
    最近更新 更多