何时以功能方式处置对象?

时间:2011-06-21 12:00:40

标签: c# functional-programming lazy-evaluation

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

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,要么阵列将固定在某个地方......在第二个假设中,我希望数组永远不会被释放。 我的错误在哪里? 非常感谢。

2 个答案:

答案 0 :(得分:3)

当您的原始引用coll设置为null时,函数fn&amp; fn2引用了相同的int[]数组。

因此,coll引用的数组在没有对它的引用之前不会被垃圾收集,包括fnfn2的参数。

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

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

答案 1 :(得分:0)

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