我有一个c#Console App(visual studio 2013 express),如下:
class Program
{
static void Main(string[] args)
{
var max = 1;
for (int i = 0; i < max; i++)
{
var inherited = new GCInherited(i);
//you can not run, if I only create this class
//var gcbase = new GCBase(i);
//if explicit set to null, the finalizer started:
//inherited = null;
}
GC.Collect(2);
GC.WaitForPendingFinalizers();
//so do not run
//GC.WaitForFullGCApproach(-1);
//GC.WaitForFullGCComplete(-1);
Console.ReadLine();
}
}
class GCInherited : GCBase
{
public GCInherited(int nr) : base(nr) { }
~GCInherited() { Console.WriteLine("GCInherited finalizer ({0})", this.nr); }
}
class GCBase
{
public int nr { get; private set; }
public GCBase(int nr) { this.nr = nr; }
~GCBase() { Console.WriteLine("GCBase finalizer"); }
}
max=1
,则在退出程序之前,终结器仅在按下回车键后运行。max=2
,则0的终结器在输入之前运行(如预期的那样),并且终结器1仅在输入之后运行。inherited=null
,则在按Enter键之前会运行所有终结器。问题出现了:为什么?
我会非常感激任何想法。
答案 0 :(得分:0)
你期待垃圾收集的错误。
陈述你的观点:
如果max = 1,则在退出程序之前,仅在按下回车键后运行终结器。 你的for循环运行一次,因此引用GCInherited为0作为数字。由于在程序中调用了垃圾收集,因此这是对继承的对象的引用。
如果max = 2,则在输入之前运行0的终结器(如预期的那样),并且仅在输入之后运行1的终结器。 同样的thign在这里发生,除了事实上第一次引用数字0的GCInherited丢失了,因为你通过初始化一个新的GCInherited数字1覆盖它并将其写入继承。
如果uncomment inherited = null,则在按Enter键之前运行所有终结器。 当然,因为不再有任何GcInherited对象的引用。