对象会超出范围吗?

时间:2013-06-17 04:22:13

标签: c# .net destructor

快速提问。

考虑这段代码

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?
    }
}

现在,当我运行Test1Tile的终结器时  叫做?那么Test2呢?

3 个答案:

答案 0 :(得分:3)

答案是否定的。

在垃圾收集器决定它想要之前,对象不会完成。从来没有像C ++的delete那样远程做任何事情。你只需要分配新的内存部分并更改指针(粗略地)。

如评论中所述:终结者(C#)和Destructors(C ++)不一样。

答案 1 :(得分:1)

关于析构函数(正确的名称是“终结者”)在C#中的事情是你永远不知道它们什么时候被调用。只要对象超出范围,就可以调用它。它可以在程序结束时调用。在某些情况下,甚至可能根本不会调用它们。这完全取决于垃圾收集器。

所以不要在系统逻辑中使用析构函数。当你应该使用析构函数时,并没有那么多的情况。

答案 2 :(得分:0)

您的代码不完整。如果它已经完成,那么引用对象将被链接为CollisionHandler->Collision->Tile,因此无论如何你的被忽略的Tile都不会被垃圾收集器收集。

.NET GC是非确定性的,所以如果你正在寻找像自动管理的确定性析构函数这样的东西,那么你就不走运了。 .NET框架为需要确定性清理的情况提供IDispose接口,例如文件I / O操作,但消费者必须明白这一点并明确地调用Dispose或使用C#中的using关键字等语言功能。