对成员变量的引用-所有者不受GC约束
本文关键字:GC 约束 所有者 成员 变量 引用 | 更新日期: 2023-09-27 18:26:42
考虑下面的示例(代码)。从Main
函数进行对GetA
的调用,该调用返回对在函数GetA
中创建的对象b
的成员变量a
的引用。请注意,在GetA
返回后,我们不再有对局部变量b
最初引用的对象的任何引用。然后我们通过调用GC.Collect()
来强制收集。
我可以看到B
的最终代码在Main
方法的最后一行之前运行,这让我相信下面的代码格式不正确?
问题:下面的代码格式不正确?如果是这样,为什么我们仍然可以访问类型为B
的对象的成员a
,即使该对象已被销毁/收集?
using System;
class A
{
public int x = 5;
}
class B
{
public A a = new A();
~B()
{
Console.WriteLine("Finalization code running for B.");
}
}
class Program
{
static A GetA()
{
B b = new B(); // <- Allocate object of type B on the managed heap
return b.a; // <- We return a (copy-of) reference to a member of B
}
static void Main(string[] args)
{
A a = GetA();
// Force a garbage collection
GC.Collect();
GC.WaitForPendingFinalizers();
// This works fine, but is this valid code?
// "Owner of" a (object of type B allocated in GetA) is dead!
Console.WriteLine("a.x = {0}", a.x);
}
}
为什么我们仍然可以访问类型B 对象的成员a
我们无法访问B.a
。我们有权访问一个曾经被B.a
引用的对象。
在GetA
方法中创建的B
的实例创建了A
的新实例,并将对其的引用存储在B.a
字段中。A
的这个实例是一个单独的对象,只要它是可访问的,就不会被收集。