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

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?

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

    }

}

In this simplistic example, when I call RemoveLastClass1Instance() within Class2 will the Class1 instance be garbage collected or does it remain to hold reference to OnClass1DoSomething() via Action<string>? My goal is to completely remove Class1 instances and have them garbage collected.

EDIT: (further to Jon Skeet's comments, I added the following code to better understand

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

    }

}
Jon Skeet
people
quotationmark

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?

No. If the delegate instance were still referenced elsewhere, and it had a target of the Class1 instance, then it would prevent the instance of Class1 from being garbage collected - but as it is, the target of the Action<string> is an instance of Class2.

Basically, there's nothing magical about delegates when it comes to garbage collection. If the delegate refers to an instance method, the target of that instance is held as a reference... so if the delegate is still reachable, the target of the delegate is still reachable. In your case, the delegate itself isn't reachable, and you're apparently not worried about whether or not the Class2 instance can be garbage collected.

The change to use an event doesn't affect this at all - it's still the instance of Class1 having a reference (via the delegate) to the original instance of Class2... the only reference to the Class1 instance from Class2 is via the list.

people

See more on this question at Stackoverflow