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

标签 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实例被垃圾收集还是仍然保留对 OnClass1DoSomething() 的引用通过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?

没有。如果委托(delegate)实例仍在其他地方被引用,并且它的目标为 Class1实例,那么它将阻止 Class1 的实例避免被垃圾收集 - 但事实上, Action<string> 的目标是 Class2 的一个实例.

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

使用事件的更改根本不会影响此 - 它仍然是 Class1 的实例(通过委托(delegate))引用 Class2 的原始实例...唯一引用 Class1来自Class2的实例通过列表。

关于c# - 当删除对类实例的所有其他引用时,Action<T> 是否会阻止封闭的类实例被 GC ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32627162/

相关文章:

c# - 使用 Nest Elastic 根据术语中的单词数进行搜索

html - 如何引用 HTML 页面的特定位置?

ios - CADisplayLink 回调是否总是在主线程上运行?

c# - 将机器人框架 Luis 与 QnA 作为 Intent 集成,然后在进入 QnA 后重新询问用户

c# - 没有默认数据库时的 Entity Framework 6 和迁移

c# - 我如何在 C# 中将 List<Interface> 转换为 List<Class>

rust - 为什么不能在同一结构中存储值和对该值的引用?

delphi - 有没有可以为 Delphi 2010 自动建议单位引用的工具?

javascript - Cordova 插件 - 回调仅执行一次

c++ - ROS:将回调函数和对象成员绑定(bind)到订阅者节点