C# 如果实例未被引用,但其回调被引用,则该实例是否会被垃圾收集?
我希望我能正确地解释这一点 如果有一个名为EventHandler的类,并且它是在单个方法调用的范围内通过“new”关键字创建的(下面的示例),我的理解是,一旦方法结束,EventHandler的实例应该标记为垃圾收集,因为它现在已超出范围 现在,如果在创建这个新EventHandler实例的方法调用中,EventHandler的一个方法作为回调操作传递给另一个方法,但回调直到EventHandler超出范围后很久才会触发,那么会发生什么 根据我的理解,如果发生上述情况,回调将抛出异常,因为它的实例不再是活动的,因为它已被垃圾收集。我是对的,还是事实上EventHandler的一个方法被用作回调这将导致EventHandler不会被垃圾收集,直到对该回调的引用不再存在,即使没有任何东西直接引用该实例到EventHandler 例如:C# 如果实例未被引用,但其回调被引用,则该实例是否会被垃圾收集?,c#,.net,reference,delegates,garbage-collection,C#,.net,Reference,Delegates,Garbage Collection,我希望我能正确地解释这一点 如果有一个名为EventHandler的类,并且它是在单个方法调用的范围内通过“new”关键字创建的(下面的示例),我的理解是,一旦方法结束,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属性。这让它活了下来。我不知道,很酷!谢谢你的书面答覆@兰登马丁当然。。。任何时候都可以。我不知道,很酷!谢谢你的书面答覆@兰登马丁当然。。。随时都可以。