如果没有引用实例但是它的回调是,实例是否会被垃圾回收?

时间:2014-09-15 04:48:34

标签: c# .net reference delegates garbage-collection

我希望我能正确解释这一点。

如果有一个名为EventHandler的类,它是在单个方法调用范围内通过'new'关键字创建的(下面的示例),我的理解是,一旦方法结束,EventHandler的实例应该标记为垃圾收集,因为它已经超出了范围。

现在如果在创建这个新的EventHandler实例的方法调用中会发生什么事情,EventHandler的方法作为回调Action传递给另一个方法但是回调在EventHandler超出范围之后很久才会触发?

根据我的理解,如果上述情况发生,回调将抛出一个异常,因为它的实例不再存在,因为它已被垃圾收集。我是正确的还是事实上,EventHandler的一个方法被用作回调,这将导致EventHandler不被垃圾收集,直到对该回调的引用不再,即使没有任何东西直接将该实例引用到EventHandler? / p>

示例:

Public void SomeMethod()
{
    var eventHandler = new EventHandler();

    //The callback below does not fire until AFTER 'SomeMethod' has ended
    RegisterCallBackForSomeEventMethod(eventHandler.SomeMethodToUseAsACallBack);

}   //SomeMethod has ended, 'eventHandler' has now fallen out of scope

1 个答案:

答案 0 :(得分:4)

实例将进行垃圾回收。

这里没有特别的待遇。不会收集此实例,因为委托在Target属性中保留对它的引用。只要您保留对您发送给RegisterCallBackForSomeEventMethod的代理人的引用,您实际上也会保留对EventHandler实例的引用。

您可以在这个简单的示例中轻松看到:

private static void Main()
{
    var eventHandler = new EventHandler();
    RegisterCallBackForSomeEventMethod(eventHandler.SomeMethodToUseAsACallBack);
}

private static void RegisterCallBackForSomeEventMethod(Action action)
{
    Console.WriteLine(action.Target.GetType());
}

输出:

  

Sandbox.EventHandler