Когда объект расположен в функциональном подходе? - PullRequest
1 голос
/ 21 июня 2011

Я озадачен этим сценарием.Рассмотрим следующий базовый код:

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" должен быть удален, потому что он заменен новым набором.Тем не менее, первая функция все еще оценивает правильно.На данный момент, либо я должен подождать более долгое время для GC, либо массив будет где-то закреплен ... во второй гипотезе, я ожидаю, что массивы никогда не будут освобождены.Где моя ошибка?Заранее большое спасибо.

Ответы [ 2 ]

3 голосов
/ 21 июня 2011

Хотя исходная ссылка coll установлена ​​на ноль, функции fn & fn2 имеют ссылку на тот же массив int[].

Следовательно, массив, на который ссылается coll, не будетсобирать мусор до тех пор, пока на него больше не будет ссылок, включая аргументы fn и fn2.

Я знаю, что параметр в Test является копией, но это копия ссылки наобъект массива, а не копия самого массива.

Термины, которые я использовал, могут быть неверными.Но, надеюсь, это поможет объяснить это.

0 голосов
/ 21 июня 2011

Измените GC.WaitForPendingFinalizers(); на GC.Collect();.Это вызывает сборку мусора для очистки памяти.

...