这肯定会发生。例如,这里有一个实例可以在您仍在执行其构造函数时完成的演示:
class Program
{
private static int _lifeState;
private static bool _end;
private sealed class Schrodinger
{
private int _x;
public Schrodinger()
{
//Here I'm using 'this'
_x = 1;
//But now I no longer reference 'this'
_lifeState = 1;
//Keep busy to provide an opportunity for GC to collect me
for (int i=0;i<10000; i++)
{
var garbage = new char[20000];
}
//Did I die before I finished being constructed?
if (Interlocked.CompareExchange(ref _lifeState, 0, 1) == 2)
{
Console.WriteLine("Am I dead or alive?");
_end = true;
}
}
~Schrodinger()
{
_lifeState = 2;
}
}
static void Main(string[] args)
{
//Keep the GC churning away at finalization to demonstrate the case
Task.Factory.StartNew(() =>
{
while (!_end)
{
GC.Collect();
GC.WaitForPendingFinalizers();
}
});
//Keep constructing cats until we find the desired case
int catCount = 0;
while (!_end)
{
catCount++;
var cat = new Schrodinger();
while (_lifeState != 2)
{
Thread.Yield();
}
}
Console.WriteLine("{0} cats died in the making of this boundary case", catCount);
Console.ReadKey();
}
}
为了使它工作,您需要发出一个 Release 版本并在 Visual Studio 之外运行它(否则调试器会插入阻止该效果的代码。)我已经使用针对 .NET 4.0 x64 的 VS 2010 对此进行了测试。
您可以调整“保持忙碌”循环中的迭代,以影响 Cat 在其完成构建之前最终确定的概率。