Дополнительные классы и структуры .NET

Отложенная инициализация и тип Lazy

Последнее обновление: 06.01.2022

Приложение может использовать множество классов и объектов. Однако есть вероятность, что не все создаваемые объекты будут использованы. Особенно это касается больших приложений. Например:

class Reader
{
    Library library = new Library();
    public void ReadBook()
    {
        library.GetBook();
        Console.WriteLine("Читаем бумажную книгу");
    }

    public void ReadEbook()
    {
        Console.WriteLine("Читаем книгу на компьютере");
    }
}

class Library
{
    private string[] books = new string[99];

    public void GetBook()
    {
        Console.WriteLine("Выдаем книгу читателю");
    }
}

Есть класс Library, представляющий библиотеку и хранящий некоторый набор книг в виде массива. Есть класс читателя Reader, который хранит ссылку на объект библиотеки, в которой он записан. У читателя определено два метода: для чтения электронной книги и для чтения обычной книги. Для чтения обычной книги необходимо обратиться к методу класса Library, чтобы получить эту книгу.

Но что если читателю вообще не придется читать обычную книгу, а только электронные, например, в следующем случае:

Reader reader = new Reader();
reader.ReadEbook();

В этом случае объект library в классе читателя никак не будет использоваться и будет только занимать место памяти. Хотя надобности в нем не будет.

Для подобных случаев в .NET определен специальный класс Lazy<T>. Изменим класс читателя следующим образом:

class Reader
{
    Lazy<Library> library = new Lazy<Library>();
    public void ReadBook()
    {
        library.Value.GetBook();
        Console.WriteLine("Читаем бумажную книгу");
    }

    public void ReadEbook()
    {
        Console.WriteLine("Читаем книгу на компьютере");
    }
}

Класс Library остается прежнем. Но теперь класс читателя содержит ссылку на библиотеку в виде объекта Lazy<Library>. А чтобы обратиться к самой библиотеке и ее методам, надо использовать выражение library.Value - это и есть объект Library.

Что меняет в поведении класса Reader эта замена? Рассмотрим его применение:

Reader reader = new Reader();
reader.ReadEbook();
reader.ReadBook();

Непосредственно объект Library задействуется здесь только на третьей строке в методе reader.ReadBook(), который вызывает в свою очередь метод library.Value.GetBook(). Поэтому вплоть до третьей строки объект Library, используемый читателем, не будет создан. Если мы не будем применять в программе метод reader.ReadBook(), то объект библиотеки тогда вообще не будет создан, и мы избежим лишних затрат памяти. Таким образом, Lazy<T> гарантирует нам, что объект будет создан только тогда, когда в нем есть необходимость.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850