Как да извършите мързелива инициализация в C #

Мързеливата инициализация е техника, която отлага създаването на обект до първия път, когато е необходим. С други думи, инициализацията на обекта се извършва само при поискване. Имайте предвид, че термините мързелива инициализация и мързелива инстанция означават едно и също нещо - те могат да се използват взаимозаменяемо. Като се възползвате от ленивата инициализация, можете да подобрите производителността на приложението, като избягвате ненужни изчисления и консумация на памет. В тази статия ще разгледаме как можем да извършим мързелива инициализация в C #.

Нека разберем мързеливото зареждане с прост пример. Помислете за два класа Customerи Order. В Customerклас съдържа Ordersимот, който от своя страна препраща към колекция от копия на Orderкласа. В Ordersколекцията може да съдържа голямо количество данни, и дори може да се нуждаят от връзка с база данни, за да се свърже с базата данни и извличане на записи. В такъв случай няма смисъл да зареждаме данни в Ordersсвойството, докато не се нуждаем от данните. Мързеливата инициализация ни позволява да зареждаме Ordersколекцията само когато са поискани данните.

Използване на клас Мързел в C #

Въпреки че можете да напишете свой собствен потребителски код, за да приложите мързелива инициализация, Microsoft препоръчва Lazyвместо това да използвате класа. В Lazyкласа в Systemпространството от имена в C # е въведена като част от .Net Framework 4.0 за осигуряване на конци-безопасен начин за изпълнение на късна инициализация. Можете да се възползвате от този клас, за да отложите инициализацията на ресурсоемки обекти във вашето приложение.

Когато използвате Lazyкласа, трябва да посочите типа обект, който възнамерявате да създадете мързеливо в аргумента на типа. Имайте предвид, че ленивата инициализация се случва, когато осъществявате достъп до Lazy.Valueсвойството. Ето пример за това как Lazyможе да се използва класът:

Мързелив
   
     поръчки = нови Мързеливи
    
     ();
     

IEnumerable резултат = lazyOrders.Value;

Сега, помислете за два класа Authorи Blog. Един автор може да пише много публикации в блога, така че да има един-към-много връзката между Authorи Blogкласове, както е показано на кодовия фрагмент по-долу.

публична класа Автор

    {

        public int Id {get; комплект; }

        публичен низ FirstName {get; комплект; }

        публичен низ LastName {get; комплект; }

        публичен низ Адрес {get; комплект; }

        публичен списък Блогове {get; комплект; }

    }

    публичен клас Блог

    {

        public int Id {get; комплект; }

        публичен низ Заглавие {get; комплект; }

        публичен DateTime PublicationDate {get; комплект; }

    }

Обърнете внимание, че един-към-много връзката между Authorи Blogкласове са представени с помощта на Listсобственост (на вид Blog) в Authorклас. Използвайки това свойство, Authorкласът може да събира колекция от един или повече екземпляра на Blogкласа.

Сега да предположим, че трябва да показваме само детайлите на даден автор (име, фамилия и адрес) в потребителския интерфейс. В този случай няма смисъл да се зареждат подробности за блога за автора; искаме мързеливо да заредим подробностите за блога. Ето актуализирания Authorклас, който отговаря на тази нужда. Обърнете внимание на използването на Lazyкласа.

публична класа Автор

    {

        public int Id {get; комплект; }

        публичен низ FirstName {get; комплект; }

        публичен низ LastName {get; комплект; }

        публичен низ Адрес {get; комплект; }

        обществен Мързел Блогове => нов Мързел (() => GetBlogDetailsForAuthor (this.Id));

        частен IList GetBlogDetailsForAuthor (int Id)

        {

       // Напишете код тук, за да извлечете всички подробности за блога за автор.

        }

    }

Използване на общия клас Lazy в C #

Нека сега разгледаме как можем да се възползваме от общ Lazyклас за реализиране на дизайнерския модел на Singleton. (Можете да прочетете статията ми за дизайна на Singleton тук.) Следващата версия на StateManagerкласа е безопасна за нишки. В същото време демонстрира мързелива инициализация. Имайте предвид, че изричният статичен конструктор е използван, за да се гарантира, че компилаторът C # не маркира типа като beforefieldinit.

публично запечатан клас StateManager

    {

        private StateManager ()

        {

        }

        публичен статичен екземпляр на StateManager

        {

            вземете

            {

                връщане Nested.obj;

            }

        }

        частен клас Вложен

        {

            статично вложено ()

            {

            }

            вътрешен статичен само за четене StateManager obj = new StateManager ();

        }

    }

Ето едно мързеливо изпълнение на StateManagerкласа, което използва Lazyкласа. Можете да видите как Lazyкласът улеснява прилагането на мързел. 

публична класа StateManager

    {

        частен статичен само за четене Lazy obj = new Lazy (() => new StateManager ());

        private StateManager () {}

        публичен статичен екземпляр на StateManager

        {

            вземете

            {

                return obj.Value;

            }

        }

    }

Разгледайте Instanceимота от StateManagerкласа по-горе. Имайте предвид, че Valueсвойството, което виждате в горния пример за код, е само за четене. Поради тази причина няма зададен аксесоар.

Мързеливата инициализация е отлична техника за оптимизиране на производителността, която ви позволява да отложите инициализацията на обекти, които консумират значителни ресурси на процесора и паметта, докато не са ви абсолютно необходими. Възползвайте се от ленивата инициализация, за да подобрите производителността на вашите приложения.