Скорее всего, вы использовали или, по крайней мере, видели ранее использованное ключевое слово lazy. Однако вы никогда не задумывались о том, каковы истинные возможности ленивого хранимого свойства. Я хочу рассказать вам о том, что такое ленивые свойства, почему они существуют и как вы можете ими воспользоваться.

Первоначально это сообщение было опубликовано 1 неделей ранее на kristofk.com.

Земляные работы

Начальное значение лениво хранимых свойств не вычисляется и не присваивается до тех пор, пока вы не вызовете это свойство. Вы можете думать об этом как о свойстве по требованию, оно не существует в памяти, пока вы его не вызовете.

Ленивое свойство всегда должно быть переменной, поскольку константы всегда должны иметь начальное значение при инициализации экземпляра.

Ленивые хранимые свойства не являются потокобезопасными!
Если к свойству, отмеченному модификатором _2, одновременно обращаются несколько потоков, и свойство еще не было инициализировано, нет гарантии, что свойство будет инициализирован только один раз.

Когда вы используете ленивое хранимое свойство?

  1. Когда свойство зависит от внешнего источника и значение может быть неизвестно до завершения инициализации (асинхронные вызовы, такие как веб-запрос).
  2. Если начальное значение свойства требует дорогостоящей в вычислительном отношении настройки, которую не следует выполнять до тех пор, пока значение не понадобится
  3. Чтобы избежать необязательных опций, также известных как необязательные опции
  4. Держите инициализаторы в чистоте, откладывая некоторые настройки до тех пор, пока позже в жизненном цикле объекта

Самый простой способ реализовать ленивое хранимое свойство — поместить ключевое слово lazy перед переменной со значением по умолчанию. Это означает, что свойство не будет инициализировано в процессе инициализации типа. Начальное значение будет присвоено только при вызове свойства.

Еще один способ инициализировать ленивое свойство — использовать метод. Это полезно, если вы хотите разделить свойство и инициализацию или если у вас длинная и сложная инициализация. Для этого вам нужно создать метод инициализации и вызвать его для свойства.
В этом примере я использовал числа Фибоначчи, так как они могут требовать значительных вычислительных ресурсов. Я сделал этот пример неоптимизированным, чтобы подчеркнуть, что это не так, как вы бы реализовали это в реальной жизни.

Если вы похожи на меня и вам нравится компактность, когда она не ставит под угрозу читабельность, вы можете переместить весь код, определенный в методе инициализации, в автоматически выполняющееся замыкание.

Есть еще один способ присвоить начальное значение ленивому свойству — использовать методы типов. Этот метод основан на принципе единой ответственности и разделении типов. Это самый утомительный из всех, и я рекомендую его только в том случае, если вы действительно найдете ему хорошее применение.
Например, в моем примере у меня есть 2 класса. Один посвящен числам Фибоначчи, а другой — общему математическому классу.

Вывод

Ленивые сохраненные свойства могут быть очень полезны для оптимизации использования ОЗУ и ЦП и обеспечения удобочитаемости нашей базы кода.

Нет никаких признаков разницы в производительности между любым из вышеперечисленных методов инициализации свойства.

Если у вас есть какие-либо вопросы, вы можете задать их мне в комментариях или в Твиттере @kristofkocsis.

Если вы хотите узнать больше о ленивых хранимых свойствах, я рекомендую следующие ресурсы:

Первоначально опубликовано на сайте kristofk.com 14 марта 2018 г.