当所有其他对 class 实例的引用被删除时,Action<T> 是否会阻止封闭的 class 实例被 GC 处理?

Does Action<T> prevent enclosing class instance to be GCed when all other references to class instance are removed?

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

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)
    {

    }

}

在这个简单的示例中,当我在 Class2 中调用 RemoveLastClass1Instance() 时,Class1 实例将被垃圾收集还是通过 Action<string>?我的目标是完全删除 Class1 个实例并将它们作为垃圾回收。

编辑:(根据 Jon Skeet 的评论,我添加了以下代码以更好地理解

public class Class1
{
    public event Action<string> Event;

    public Class1()
    {

    }

    public void DoSomething(string msg)
    {
        var handle = Event;
        if (handle != null)
        {
            handle(msg);
        }
    }

}

public class Class2
{
    private List<Class1> _class1s;

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

    public void AddClass1Instance()
    {
        var newClass1Instance = new Class1();
        newClass1Instance.Event += OnClass1DoSomething;
        _class1s.Add(newClass1Instance);
    }

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

    private void OnClass1DoSomething(string msg)
    {

    }

}

I wonder whether Action<T> prevents an enclosing class instance to be garbage collected when all other references to such class instance are removed during runtime?

没有。如果委托实例仍在其他地方引用,并且它具有 Class1 实例的目标,then 它将阻止 Class1 的实例被垃圾收集 -但事实上,Action<string> 的目标是 Class2.

的一个实例

基本上,在垃圾回收方面,委托并没有什么神奇之处。如果委托引用实例方法,则该实例的目标将作为引用保存...因此,如果委托仍然可以访问,则委托的目标仍然可以访问。在你的例子中,委托本身是不可访问的,你显然不担心 Class2 实例是否可以被垃圾收集。

使用事件的更改根本不会影响这一点 - 它仍然是 Class1 的实例具有对 Class2 的原始实例的引用(通过委托)... Class2 中的 Class1 实例的引用是通过列表实现的。