当以函数方法处理对象时



我对这种情况感到困惑。考虑以下基本代码:

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();
    }
}

这个目的完全没有用,但我在问自己,这两个整数数组什么时候会被处理掉。"Test"函数应该返回另一个函数,该函数在被调用之前不会进行求值。这是通过使用调试器进行验证的。到目前为止,第一个"coll"数组应该被丢弃,因为它被新的集合所取代。但是,第一个函数的计算结果仍然正确。在这一点上,要么我必须等待GC更长的时间,要么数组将被固定在某个地方。。。在第二个假设中,我预计阵列永远不会被释放。我的错误在哪里?提前非常感谢。

当原始引用coll设置为null时,函数fn&fn2具有对相同CCD_ 2阵列的引用。

因此,coll引用的数组将不会被垃圾收集,直到不再有对它的引用,包括对fnfn2的参数。

我知道Test中的参数是一个副本,但它是对数组对象的引用的副本,而不是数组本身的副本。

我使用的术语可能不正确。但希望这有助于解释它。

GC.WaitForPendingFinalizers();更改为GC.Collect();。这会调用垃圾回收来清理内存。

最新更新