Язык программирования C#9 и платформа .NET5. Страница 194
private Song[] _allSongs = new Song[10000]; public AllTracks() { // Предположим, что здесь производится // заполнение массива объектов Song. Console.WriteLine("Filling up the songs!"); } }}<b>// MediaPlayer.cs</b><b>using System;</b><b>namespace LazyObjectInstantiation</b><b>{</b><b> // Объект MediaPlayer имеет объекты AllTracks.</b> class MediaPlayer { // Предположим, что эти методы делают что-то полезное. public void Play() { /* Воспроизведение композиции */ } public void Pause() { /* Пауза в воспроизведении */ } public void Stop() { /* Останов воспроизведения */ } private AllTracks _allSongs = new AllTracks(); public AllTracks GetAllTracks() { // Возвратить все композиции. return _allSongs; } }}В текущей реализации
MediaPlayerGetAllTracks()AllTracksSongusing System;using LazyObjectInstantiation;Console.WriteLine("***** Fun with Lazy Instantiation *****\n");// В этом вызывающем коде получение всех композиций не производится,// но косвенно все равно создаются 10 000 объектов!MediaPlayer myPlayer = new MediaPlayer();myPlayer.Play();Console.ReadLine();Безусловно, лучше не создавать 10 000 объектов, с которыми никто не будет работать, потому что в результате нагрузка на сборщик мусора .NET Core намного увеличится. В то время как можно вручную добавить код, который обеспечит создание объекта
_allSongsБиблиотеки базовых классов предоставляют удобный обобщенный класс по имени
Lazy<>Systemmscorlib.dllAllTracksMediaPlayer// Объект MediaPlayer имеет объект Lazy<AllTracks>.class MediaPlayer{ ... private Lazy<AllTracks> _allSongs = new Lazy<AllTracks>(); public AllTracks GetAllTracks() { // Возвратить все композиции. return _allSongs.Value; }}Помимо того факта, что переменная-член
AllTracksLazy<>GetAllTracks()AllTracksSongValueLazy<>Взгляните, как благодаря такому простому изменению приведенный далее модифицированный код будет косвенно размещать объекты
SongGetAllTracks()Console.WriteLine("***** Fun with Lazy Instantiation *****\n");// Память под объект AllTracks здесь не выделяется!MediaPlayer myPlayer = new MediaPlayer();myPlayer.Play();// Размещение объекта AllTracks происходит// только в случае вызова метода GetAllTracks().MediaPlayer yourPlayer = new MediaPlayer();AllTracks yourMusic = yourPlayer.GetAllTracks();Console.ReadLine();На заметку! Ленивое создание объектов полезно не только для уменьшения количества выделений памяти под ненужные объекты. Этот прием можно также использовать в ситуации, когда для создания члена применяется затратный в плане ресурсов код, такой как вызов удаленного метода, взаимодействие с реляционной базой данных и т.п.
Настройка процесса создания данных Lazy<>
При объявлении переменной
Lazy()