2012-11-16 73 views
3

我花了一些時間學習C#中的弱引用是如何工作的,而且我遇到了這種奇怪的行爲。奇怪的C#弱參考行爲

在下面的示例代碼中,第一個測試通過,第二個失敗。看起來你不能在構造之後但在創建一個弱引用之前修改對象的一個​​實例,而不能停止以預期方式工作的弱引用。

private class Simple 
{ 
    public Simple() { X = "Hello"; } 
    public string X { get; set; } 
} 

[Test] 
public void CreatingWeakReferenceBeforeModifying() 
{ 
    var a = new Simple(); 
    var aRef = new WeakReference(a); 
    a.X = "World"; // First modification to a after creating reference 
    a = null; 
    GC.Collect(); 
    Assert.That(aRef.IsAlive, Is.False); // This assertion passes 
} 

[Test] 
public void CreatingWeakReferenceAfterModifying() 
{ 
    var b = new Simple {X = "World"}; // First mod to b before creating ref 
    var bRef = new WeakReference(b); 
    b = null; 
    GC.Collect(); 
    Assert.That(bRef.IsAlive, Is.False); // This assertion fails 
} 

我在這裏錯過了什麼嗎?

回答

4

嫌疑人你只會在某些情況下看到這一點 - 尤其是在調試版本下,尤其是在調試器下。

本聲明:

var b = new Simple {X = "World"}; 

有效的是:

var tmp = new Simple(); 
tmp.X = "World"; 
var b = tmp; 

所以,即使你設置b爲空,還是有它具有對對象的引用棧上的局部變量。

當在優化方案中運行,我期望的GC注意到局部變量都不會再次讀取,而忽略了它作爲一個GC根 - 但可能的方式你運行它ISN 't讓GC變得咄咄逼人。

+0

這會教我嘗試和簡化代碼:) – Scroog1