c# - 在哪个类委托(delegate)实例上被调用?

标签 c# events delegates

考虑这段代码,

public class A
{
     //...
     void f()
     {  
          B b = new B();
          b.SomeEvent += this.SomeMethod;
     }
     void SomeMethod() {}
 }

 public class B
 {
     //...

     public event SomeEventHandler SomeEvent;

     void h()
     {  
          if ( SomeEvent != null )
          {
               SomeEvent.invoke();
          }
     }
 }

在此代码片段中,SomeEvent.invoke() 实际上调用了 A 类的 SomeMethod()。所以在这一点上,我有几个问题:

  • A 的哪个实例调用了 SomeMethodB 如何知道要调用委托(delegate)的实例? CLR 如何在这里工作?
  • 另外,SomeMethod 是一个private 方法,那么B 为什么能够从类 外部调用这个方法?

编辑:

阅读前几个答案后,我开始知道 Delegate 有一个 Target 属性,在该属性上调用委托(delegate)。但是我无法真正理解这个 Target 属性到底是在哪一步设置的?谁定的?当我编写 b.SomeEvent += this.SomeMethod; 时,它是否也设置了 Target 属性?具体如何?

最佳答案

 b.SomeEvent += this.SomeMethod

这里有很多糖分让您看不到真正发生的事情。写出来,它类似于这样:

 b.SomeEvent.add(new MulticastDelegate(this, SomeMethod));     // not legal code

其中 add() 是事件的添加访问器,编译器会在您未明确声明自己的访问器时自动生成一个。委托(delegate)构造函数的第一个参数是您要询问的对象实例,即委托(delegate)对象的 Target 属性。请注意,这有副作用,事件订阅保留对您的 b 对象的引用。这会阻止它收集垃圾,这在调用事件时会很糟糕。

这也可能是一个问题,您可能会无意中泄漏对象引用。在您的代码中没有取消订阅事件处理程序的好方法,因此 A 对象将与您调用 h() 的 B 对象一样存在。

关于c# - 在哪个类委托(delegate)实例上被调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5436713/

相关文章:

c# - 从抽象基类返回规范表示子类是否可以接受?

c# - 使用位运算符

android - 检测 Android 上已读的短信

iphone - 在 Objective-C 中实现委托(delegate)模式

c# - 如何引用 UDF 中的一系列单元格

C++事件模板类

javascript - 如何将自定义 jQuery 事件冒泡到 window.document?

c# - 如何在调用方法中定义回调函数?

ios - 为什么保留委托(delegate)是错误的所有替代方案......?

c# - 如何在 C# 中访问用户控件的属性