C# 重新创建对';这';在.net析构函数中?
在.net中编写以下内容合法吗C# 重新创建对';这';在.net析构函数中?,c#,.net,garbage-collection,destructor,finalizer,C#,.net,Garbage Collection,Destructor,Finalizer,在.net中编写以下内容合法吗 public class A { public int i = 0; ~A() { Aref = this; } } public static A Aref; static void Main(string[] args) { Aref = new A(); int gen = GC.GetGe
public class A
{
public int i = 0;
~A()
{
Aref = this;
}
}
public static A Aref;
static void Main(string[] args)
{
Aref = new A();
int gen = GC.GetGeneration(Aref);
Aref = null;
GC.Collect(gen, GCCollectionMode.Forced);
GC.WaitForPendingFinalizers();
Console.WriteLine(Aref.i);
Console.ReadLine();
}
它可以正常工作,并按预期将“0”写入控制台,但我想知道它是否保证始终工作
有人知道幕后发生了什么吗?这叫复活,是合法的。谷歌搜索“.net对象复活”(以及类似的术语),您会发现如下内容:
只要确保这些僵尸物体不会回来,并试图吃掉你的大脑或其他东西。就像所有的巫术一样,这是危险的东西。(主要是因为类层次结构中较高级别的终结器可以释放一些基本资源。还要注意,如果对象“未引用”,则终结器不会再次运行,除非调用
GC.ReRegisterForFinalize
),因为第一次垃圾收集不会收集实例,所以终结器可以工作。它只是安排实例运行其终结器。然后,终结器将为实例创建一个新的根,因此,当下一次收集发生时,实例实际上是根实例,因此无法进行收集
你应该非常小心处理这个棘手的问题。如果使用终结器来确保对象已被释放,这实际上违反了协议,因为一次性模式表示,如果已释放实例在被释放后使用,则应抛出ObjectDisposedException 垃圾收集器将对象分为三组:
除非任何地方都没有根引用,否则无法删除对象。最后定稿是删除前的一个独特阶段;请注意,当一个对象注册以进行终结时,它直接或间接引用的所有对象都将受到保护,不会被删除,但不会被终结。您想做什么?阻止收集物品?我什么都不想做。只是想知道它是如何工作的:)嗯,我认为复活只适用于weakreference。弱引用可以设置为跟踪复活,但要复活,当然需要创建一个根正常引用。“类层次结构中更高级别的终结器可以释放一些基本资源”--将在父类之前调用子类终结器;这与构造顺序相反。我听说,如果在构造函数中抛出异常作为安全检查,这种方法可能(也可能不)存在一些可能的问题-你不应该听那些说这种话的人:)