Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю
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;
}
}
}
В текущей реализации
MediaPlayer
GetAllTracks()
AllTracks
Song
using 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<>
System
mscorlib.dll
AllTracks
MediaPlayer
// Объект MediaPlayer имеет объект Lazy<AllTracks>.
class MediaPlayer
{
...
private Lazy<AllTracks> _allSongs = new Lazy<AllTracks>();
public AllTracks GetAllTracks()
{
// Возвратить все композиции.
return _allSongs.Value;
}
}
Помимо того факта, что переменная-член
AllTracks
Lazy<>
GetAllTracks()
AllTracks
Song
Value
Lazy<>
Взгляните, как благодаря такому простому изменению приведенный далее модифицированный код будет косвенно размещать объекты
Song
GetAllTracks()
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()