C# System.WeakReference的奇怪行为

C# System.WeakReference的奇怪行为,c#,reference,weak-references,C#,Reference,Weak References,我正在研究C#中的系统.WeakReference,发现其中有一个奇怪的行为。请查看下面的代码: public class MainClass { public class Fruit { public Fruit(string name) { this.Name = name; } public string Name { get; private set; } } public static void Main()

我正在研究C#中的
系统.WeakReference
,发现其中有一个奇怪的行为。请查看下面的代码:

public class MainClass
{
    public class Fruit
    {
        public Fruit(string name) { this.Name = name; }

        public string Name { get; private set; }
    }

    public static void Main()
    {
        Fruit orange = new Fruit("Orange");
        Fruit orangeStrong = orange;
        WeakReference orangeWeak = new WeakReference(orange);

        orange = null;
        orangeStrong = null;

        GC.Collect(0, GCCollectionMode.Forced);
        GC.WaitForFullGCComplete();

        Fruit orangeNew = ((Fruit)orangeWeak.Target);
        Console.WriteLine(orangeNew.Name);
    }
}
正如预期的那样,此代码会抛出
NullReferenceException
,因为
orange
是垃圾收集的。但是,在底部添加一行,如下所示:

public class MainClass
{
    public class Fruit
    {
        public Fruit(string name) { this.Name = name; }

        public string Name { get; private set; }
    }

    public static void Main()
    {
        Fruit orange = new Fruit("Orange");
        Fruit orangeStrong = orange;
        WeakReference orangeWeak = new WeakReference(orange);

        orange = null;
        orangeStrong = null;

        GC.Collect(0, GCCollectionMode.Forced);
        GC.WaitForFullGCComplete();

        Fruit orangeNew = ((Fruit)orangeWeak.Target);
        Console.WriteLine(orangeNew.Name);
        Console.WriteLine(orangeNew == null ? "" : orangeNew.Name);
    }
}
使
orange
不再被垃圾收集,代码运行时不会出现异常


这种奇怪的行为有什么原因吗?

只是检查一下-您是从发布版本而不是调试运行这些,对吗?(调试版本可以延长对象的生命周期)第一个版本也会在调试版本上为我打印“橙色”:当我编译作为发布版本发布的代码并从命令行提示符运行该程序时,两个版本都会崩溃,出现
NullReferenceException
。请注意,无论构建配置或调用
GC.Collect()
,从某种意义上说,.NET GC系统都是不确定的,即对象在技术上可能仍然是可访问的,即使您认为您已经使它们无法访问。问为什么某些东西被GC’ed或没有被GC’ed的问题没有那么有用,尤其是你的问题似乎不可靠。