c#:订阅事件意味着对该对象的引用

时间:2012-02-17 19:46:08

标签: c#

public class A
{
    public delegate void D();
    public event D E;

    ...
}

class B
{
   void Test()
   {
       A a = new A();
       a.E += () => { ... };

       a = null;
   }
}

a结束时是否可以Test()进行垃圾回收,或者由于事件订阅,仍然可以在某个地方引用它?

2 个答案:

答案 0 :(得分:3)

是的,a可以在您的示例中使用GC。它也不会引起任何问题。想一想。

Class1 a = new Class1();
Class2 b = new Class2();

a.SomeEvent += b.SomeMethod;

在此示例中,a包含对b的引用,但不是相反的引用。 a.SomeEvent成员就像List<delegate>(或接近它)。它包含对所有订阅者的引用,因此可以在需要时调用它们。

所以当a需要GC时,它可以。它将与订户列表一起销毁。 b将保持幸福,没有任何问题。

另一种方式不起作用 - b无法收集,因为a仍然持有对它的引用。如果它被收集,那么a将获得对某个地方不存在的引用,并且下一次引发事件的尝试将会爆炸。

答案 1 :(得分:2)

通过订阅对象上的事件,您将保留对该对象的引用。

您需要取消订阅才能发布参考资料。

在您的情况下,Test执行完毕后,a指向的引用将超出范围并且有资格进行垃圾回收 - 订阅的事件不会更改。

请参阅Why can .NET not have memory leaks?上的答案。