2011-06-21 33 views
1

我很困惑這種情況。 考慮以下基本代碼:什麼時候在功能方法中放置一個對象?

class Program 
{ 
    /// <summary> 
    /// Create a function that sums up any of the ints supplied 
    /// </summary> 
    private static Func<IEnumerable<int>, Func<int>> Test = (coll) => 
    { 
     //create the function 
     Func<int> fn =() => 
     { 
      return coll.Sum(); 
     }; 

     return new Func<int>(fn); 
    }; 



    static void Main(string[] args) 
    { 
     //given an ints set, create a function that sums up any of them 
     int[] coll = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 
     Func<int> fn = Test(coll); 

     //same as before: different set, and another func's instance 
     coll = new[] { 5, 5, 5, 5 }; 
     Func<int> fn2 = Test(coll); 

     //dispose any pending object 
     coll = null; 
     GC.WaitForPendingFinalizers(); 

     //evaulate both the functions in a lazy fashion 
     Console.WriteLine(fn()); //yields 45 
     Console.WriteLine(fn2()); //yields 20 

     Console.Write("Press any key..."); 
     Console.ReadKey(); 
    } 

} 

目的是絕對沒用,但我問自己,當兩個整數數組將被佈置。 「測試」函數應該返回另一個函數,該函數在被調用之前不會被評估。這通過使用調試器進行驗證。 到目前爲止,第一個「coll」數組應該被丟棄,因爲它被新的集合取代。但是,第一個函數仍然可以正確評估。 在這一點上,要麼我必須等待更長的時間,或者將數組固定在某處......在第二個假設中,我期望數組永遠不會被釋放。 我的錯誤在哪裏? 非常感謝。

回答

3

雖然您的原始參考coll設置爲空,但函數fn & fn2對同一個int[]數組有參考。

因此,coll引用的數組將不會被垃圾收集,直到沒有更多引用爲止,包括參數fnfn2

我知道Test內的參數是一個副本,但它是對數組對象的引用的副本,而不是數組本身的副本。

我使用的術語可能不正確。但希望這有助於解釋它。

+0

這是正確的!令我困惑的是,「功能」如何像一個對象一樣行事。參考文獻在哪裏? –

+1

基本上fn是一個匿名方法/委託。你在外部方法範圍內的函數引用的任何變量(在這種情況下,Test的'coll')將被保留或捕獲以在該函數內使用('fn')。 – Clinton

0

將您的GC.WaitForPendingFinalizers();更改爲GC.Collect();。這將調用垃圾收集來清理內存。

相關問題