考慮下面的例子(代碼)。從Main
函數進行到GetA
的調用,該函數返回對函數GetA
中創建的對象b
的成員變量a
的引用。請注意,在GetA
返回後,我們不再有任何對本地變量b
最初引用的對象的引用。然後我們通過致電GC.Collect()
強制收集。引用成員變量 - 所有者不受GC支持?
我可以看到在Main
方法的最後一行之前運行的B
的終結代碼,這使我相信下面的代碼是不合格的?
問題:以下代碼格式不正確嗎?如果是這樣,即使對象被銷燬/收集,我們如何仍然可以訪問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);
}
}
「不健康」你是什麼意思?一個錯誤? .NET沒有像C一樣的未定義行爲。任何情況下都不能訪問「無效」對象。 – usr
是的,我的意思是錯誤。如果我運氣好的話,GC還沒有運行,如果我運氣不好,GC已經運行。 – jensa
出於同樣的原因,我們有哈姆雷特,即使威廉莎士比亞早已被死亡率的偉大GC收集。 –