考虑以下示例(代码)。从Main
函数调用GetA
,返回对函数a
中创建的对象b
的成员变量GetA
的引用。请注意,在GetA
返回后,我们不再对本地变量b
最初引用的对象有任何引用。然后我们通过调用GC.Collect()
强制收集。
我可以看到在B
方法的最后一行之前运行的Main
的终结代码,这让我相信下面的代码格式不正确?
问题:以下代码格式不正确?如果是这样,为什么我们仍然可以访问a
类型对象的成员B
,即使该对象被销毁/收集?
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);
}
}
答案 0 :(得分:1)
为什么我们仍然可以访问B类型对象的成员a
我们无法访问B.a
。我们可以访问过去由B.a
引用的对象。
B
方法中创建的GetA
实例创建了A
的新实例,并在B.a
字段中存储了对它的引用。 A
的这个实例是一个单独的对象,只要它可以访问它就不会被收集。