对委托的引用是否构成对对象的引用(以防止垃圾回收)?

时间:2009-11-12 03:39:43

标签: c# .net delegates garbage-collection

我很难想出一个很好的方法来解释这个问题,所以让我试着通过例子来解释:

假设我有一些界面。为简单起见,我会说接口是IRunnable,它提供了一个方法Run。 (这不是真实的;它只是一个例子。)

现在,假设我有一些预先存在的类,我们称之为Cheetah,我无法改变。它存在于IRunnable之前;我无法 make 它实现我的界面。但我想使用它就像它实现IRunnable一样 - 可能是因为它有一个Run方法,或类似的东西。换句话说,我希望能够拥有期望IRunnable的代码,并且可以使用Cheetah

好的,所以我总能写出CheetahWrapper种交易。但是幽默我,让我写一些更灵活的东西 - RunnableAdapter怎么样?

我将类定义设想为:

public class RunnableAdapter : IRunnable {
    public delegate void RunMethod();

    private RunMethod Runner { get; set; }

    public RunnableAdapter(RunMethod runner) {
        this.Runner = runner;
    }

    public void Run() {
        Runner.Invoke();
    }
}

直截了当,对吧?所以有了这个,我应该可以这样打个电话:

Cheetah c = new Cheetah();
RunnableAdapter ra = new RunnableAdapter(c.Run);

现在,瞧,我有一个实现IRunner的对象,它的核心是Cheetah

我的问题是:如果我的Cheetah在某些时候超出了范围,并且达到通常会被垃圾收集的程度......它会吗?或者此RunnableAdapter对象的Runner属性是否构成对原始Cheetah的引用,以便它不会被收集?我当然希望该引用保持有效,所以基本上我想知道上面的类定义是否足够,或者是否有必要维护对底层对象的引用(比如通过一些私有的UnderlyingObject属性),防止垃圾收集。

4 个答案:

答案 0 :(得分:9)

是的,该引用仍然有效,实际上可以使用Delegate.Target属性检索 - 在代码中,ra.Runner.Target

答案 1 :(得分:4)

正如其他人所说,它算作参考。你可能会发现这个故事很有趣。 http://asserttrue.blogspot.com/2008/11/garbage-collection-causes-car-crash.html

答案 2 :(得分:2)

如果没有,那听起来就像一个破碎的垃圾收集器。

答案 3 :(得分:2)

是的,代表作为参考。在代理也无法访问之前,您的对象不会被垃圾回收。