快速提问。
考虑这段代码
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
呢?
答案 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
关键字等语言功能。