当删除对类实例的所有其他引用时,Action <t>是否阻止封闭类实例?

时间:2015-09-17 09:41:42

标签: c# reference callback garbage-collection

我想知道在运行时删除对此类实例的所有其他引用时,Action<T>是否会阻止封闭的类实例被垃圾收集?

public class Class1
{
    private Action<string> _callback;

    public Class1(Action<string> callback)
    {
        _callback = callback;
    }

    public void DoSomething(string msg)
    {
        _callback(msg);
    }

}

public class Class2
{
    private List<Class1> _class1s;

    public Class2()
    {
        _class1s = new List<Class1>();
    }

    public void AddClass1Instance()
    {
        _class1s.Add(new Class1(OnClass1DoSomething));
    }

    public void RemoveLastClass1Instance()
    {
        if(_class1s.Count > 0)
        {
            _class1s.RemoveAt(_class1s.Count - 1);
        }
    }

    private void OnClass1DoSomething(string msg)
    {

    }

}

在这个简单的示例中,当我在RemoveLastClass1Instance()内调用Class2时,Class1实例将被垃圾收集,或者是否仍然通过{{1}保留对OnClass1DoSomething()的引用}}?我的目标是完全删除Action<string>个实例并将它们收集垃圾。

编辑:(继Jon Skeet的评论之后,我添加了以下代码以便更好地理解

Class1

1 个答案:

答案 0 :(得分:4)

  

我想知道在运行时删除对此类实例的所有其他引用时,Action<T>是否会阻止封闭的类实例被垃圾收集?

没有。如果委托实例仍然在别处被引用,并且它具有Class1实例的目标,那么然后它将阻止Class1的实例被垃圾收集 - 但是因为它是的,Action<string>的目标是Class2的实例。

基本上,在垃圾收集方面,代表们并不神奇。如果委托引用实例方法,则该实例的目标将作为引用保留...因此,如果委托仍然可访问,则委托的目标仍可访问。在您的情况下,代理本身是不可访问的,您显然不担心Class2实例是否可以被垃圾收集。

使用事件的更改根本不会影响这一点 - 它仍然是Class1的实例(通过委托)引用{{1}的原始实例来自Class2的{​​{1}}实例的引用是通过列表。