繁体   English   中英

对象会超出范围吗?

[英]Would object fall out of scope?

快速提问。

考虑这段代码

public class Tile
{
    public Collision Collision;
    public Tile()
    {
        Collision = new Collision(this);
    }
    public ~Tile()
    {
        CollisionHandler.Remove(Collision);
    }
}

public class Collision
{
    public Collision()
    {
        CollisionHandler.Add(this);
    }
}

public class Main
{
    public Main()
    {
        Test1();
        Test2();
    }

    public void Test1()
    {
        Tile[,] tiles = new Tile[20,20];
        tiles[0,0] = new Tile();

        tiles[0,0] = new Tile();
        //Would calling the above call the old Tile's destructor?
    }

    public void Test2()
    {
        Tile[,] tiles = new Tile[20,20];
        tiles[0,0] = new Tile();

        Tile t = new Tile();
        tiles[0,0] = t
        //Would calling the above call the old Tile's destructor?
    }
}

现在,当我运行Test1将调用旧的Tile的终结器吗? Test2呢?

答案是不。

直到垃圾收集器决定要对象时,对象才最终确定。 您绝不会像C ++的delete那样远程进行任何操作。 您只是在分配新的内存部分并更改指针(大致)。

如评论中所述:终结器(C#)和析构函数(C ++)不同。

关于C#中的析构函数(专有名称为“ finalizers”),您永远不知道何时调用它们。 只要对象超出范围,就可以调用它。 程序结束时可以调用它。 在某些情况下,甚至根本不会调用它们。 这完全取决于垃圾收集器。

因此,请勿将析构函数用于系统逻辑。 根本没有应该使用析构函数的所有情况。

您的代码不完整。 如果已完成,则引用对象将像CollisionHandler->Collision->Tile一样进行链接,因此您被忽略的Tile将永远不会被垃圾收集器收集。

.NET GC是非确定性的,因此,如果您正在寻找自动管理的确定性析构函数之类的东西,那么您就不走运了。 .NET框架提供IDispose接口,用于需要优先进行确定性清理(例如文件I / O操作)的情况,但是使用者必须意识到这一点并明确调用Dispose或使用语言功能(例如在C#中using关键字)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM