将对象排除在范围之外
本文关键字:范围 对象 排除 | 更新日期: 2023-09-27 18:18:35
快速提问
考虑以下代码
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#中的析构函数(正确的名称是"finalizer ")就是你永远不知道什么时候会调用它们。只要对象超出作用域,就可以调用它。它可以在程序结束时调用。在某些情况下,它们甚至可能根本不被调用。这完全取决于垃圾收集器。
所以不要对系统逻辑使用析构函数。并不是所有的情况都应该使用析构函数
您的代码不完整。如果它是完整的,那么引用对象将像CollisionHandler->Collision->Tile
一样被链接起来,因此您忽略的Tile
无论如何都不会被垃圾收集器收集。
. net GC是非确定性的,所以如果你正在寻找像自动管理的确定性析构函数这样的东西,那么你就不走运了。net框架提供了IDispose
接口,用于优先考虑确定性清理的情况,例如文件I/O操作,但消费者必须意识到这一点,并显式调用Dispose
或使用语言的功能,如c#中的using
关键字。