Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ionic-framework/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如果实例未被引用,但其回调被引用,则该实例是否会被垃圾收集?_C#_.net_Reference_Delegates_Garbage Collection - Fatal编程技术网

C# 如果实例未被引用,但其回调被引用,则该实例是否会被垃圾收集?

C# 如果实例未被引用,但其回调被引用,则该实例是否会被垃圾收集?,c#,.net,reference,delegates,garbage-collection,C#,.net,Reference,Delegates,Garbage Collection,我希望我能正确地解释这一点 如果有一个名为EventHandler的类,并且它是在单个方法调用的范围内通过“new”关键字创建的(下面的示例),我的理解是,一旦方法结束,EventHandler的实例应该标记为垃圾收集,因为它现在已超出范围 现在,如果在创建这个新EventHandler实例的方法调用中,EventHandler的一个方法作为回调操作传递给另一个方法,但回调直到EventHandler超出范围后很久才会触发,那么会发生什么 根据我的理解,如果发生上述情况,回调将抛出异常,因为它的

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

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

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

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

例如:

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

实例将被垃圾收集

这里没有特殊待遇。不会收集此实例,因为委托在属性中保留对它的引用。只要保留对要发送到
RegisterCallBackForSomeEventMethod
的委托的引用,实际上也保留了对
事件处理程序
实例的引用

在这个简单的示例中,您可以很容易地看到:

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

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

Sandbox.EventHandler


实例将被垃圾收集

这里没有特殊待遇。不会收集此实例,因为委托在属性中保留对它的引用。只要保留对要发送到
RegisterCallBackForSomeEventMethod
的委托的引用,实际上也保留了对
事件处理程序
实例的引用

在这个简单的示例中,您可以很容易地看到:

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

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

Sandbox.EventHandler


垃圾收集器是您的朋友,它不会破坏您以后可以引用的对象。从C#代码中看不到的是存储在委托对象中的隐藏this引用。Delegate.Target属性。垃圾收集器是你的朋友,它不会破坏你以后可以引用的对象。从C#代码中看不到的是存储在委托对象中的隐藏this引用。Delegate.Target属性。这让它活了下来。我不知道,很酷!谢谢你的书面答覆@兰登马丁当然。。。任何时候都可以。我不知道,很酷!谢谢你的书面答覆@兰登马丁当然。。。随时都可以。