我对这种情况感到困惑。 请考虑以下基本代码:
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,要么阵列将固定在某个地方......在第二个假设中,我希望数组永远不会被释放。 我的错误在哪里? 非常感谢。
答案 0 :(得分:3)
当您的原始引用coll
设置为null时,函数fn&amp; fn2引用了相同的int[]
数组。
因此,coll
引用的数组在没有对它的引用之前不会被垃圾收集,包括fn
和fn2
的参数。
我知道Test
中的参数是副本,但它是对数组对象的引用的副本,而不是数组本身的副本。
我使用的术语可能不正确。但希望这有助于解释它。
答案 1 :(得分:0)
将您的GC.WaitForPendingFinalizers();
更改为GC.Collect();
。这会调用垃圾收集来清理内存。