Jak wykonać leniwą inicjalizację w C #

Inicjalizacja z opóźnieniem to technika, która odracza tworzenie obiektu do momentu, gdy jest to potrzebne po raz pierwszy. Innymi słowy, inicjalizacja obiektu odbywa się tylko na żądanie. Zauważ, że terminy leniwa inicjalizacja i leniwa instancja oznaczają to samo - mogą być używane zamiennie. Korzystając z leniwej inicjalizacji, można poprawić wydajność aplikacji, unikając niepotrzebnych obliczeń i zużycia pamięci. W tym artykule przyjrzymy się, jak możemy wykonać leniwą inicjalizację w C #.

Rozumiemy leniwe ładowanie na prostym przykładzie. Rozważ dwie klasy Customeri Order. CustomerKlasa zawiera Orderswłaściwość, która z kolei odwołuje się zbiór wystąpień Orderklasy. OrdersKolekcja może zawierać dużą ilość danych, a nawet mogą potrzebować połączenia z bazą danych, aby połączyć się z bazą danych i pobierania rekordów. W takim przypadku nie ma sensu ładowanie danych do Ordersnieruchomości, dopóki nie będziemy ich potrzebować. Leniwa inicjalizacja pozwala nam załadować Orderskolekcję tylko wtedy, gdy wymagane są dane.

Korzystanie z klasy Lazy w języku C #

Chociaż możesz napisać własny kod niestandardowy, aby zaimplementować leniwą inicjalizację, firma Microsoft zaleca Lazyzamiast tego użycie klasy. LazyKlasy w Systemprzestrzeni nazw w języku C # został wprowadzony jako część programu .NET Framework 4.0, aby zapewnić sposób bezpieczny wątku wdrożenia leniwe inicjowanie. Możesz skorzystać z tej klasy, aby odroczyć inicjalizację obiektów intensywnie korzystających z zasobów w aplikacji.

Korzystając z Lazyklasy, musisz określić typ obiektu, który zamierzasz leniwie tworzyć w argumencie type. Należy zauważyć, że inicjalizacja z opóźnieniem występuje podczas uzyskiwania dostępu do Lazy.Valuewłaściwości. Oto przykład Lazyużycia tej klasy:

Leniwy
   
     zamówienia = nowy Lazy
    
     ();
     

IEnumerable result = lazyOrders.Value;

Rozważmy teraz dwie klasy Authori Blog. Autor może napisać wiele postów na blogu, więc istnieje relacja jeden do wielu między klasami Authori Blog, jak pokazano w poniższym fragmencie kodu.

Klasa publiczna Autor

    {

        public int Id {get; zestaw; }

        public string FirstName {get; zestaw; }

        public string LastName {get; zestaw; }

        public string Address {get; zestaw; }

        public List Blogs {get; zestaw; }

    }

    Blog zajęć publicznych

    {

        public int Id {get; zestaw; }

        public string Title {get; zestaw; }

        public DateTime PublicationDate {get; zestaw; }

    }

Należy zauważyć, że relacja jeden do wielu między klasami Authori Blogzostała przedstawiona przy użyciu Listwłaściwości (typu Blog) w Authorklasie. Korzystając z tej właściwości, Authorklasa może przechowywać kolekcję jednego lub więcej wystąpień Blogklasy.

Załóżmy teraz, że musimy wyświetlić tylko szczegóły autora (imię, nazwisko i adres) w interfejsie użytkownika. W tym przypadku nie ma sensu ładowanie szczegółów bloga dla autora; chcemy leniwie ładować szczegóły bloga. Oto zaktualizowana Authorklasa, która odpowiada na tę potrzebę. Zwróć uwagę na użycie Lazyklasy.

Klasa publiczna Autor

    {

        public int Id {get; zestaw; }

        public string FirstName {get; zestaw; }

        public string LastName {get; zestaw; }

        public string Address {get; zestaw; }

        publiczny Leniwy Blogi => nowy Lazy (() => GetBlogDetailsForAuthor (this.Id));

        prywatny IList GetBlogDetailsForAuthor (int Id)

        {

       // Wpisz tutaj kod, aby pobrać wszystkie szczegóły bloga dla autora.

        }

    }

Używanie ogólnej klasy Lazy w języku C #

Przyjrzyjmy się teraz, jak możemy wykorzystać Lazyklasę ogólną do zaimplementowania wzorca projektowego Singleton. (Możesz przeczytać mój artykuł na temat wzorca projektowego Singleton tutaj.) Następująca wersja StateManagerklasy jest bezpieczna wątkowo. Jednocześnie demonstruje leniwą inicjalizację. Zwróć uwagę, że jawny konstruktor statyczny został użyty, aby upewnić się, że kompilator C # nie oznacza typu jako beforefieldinit.

publicznie zapieczętowana klasa StateManager

    {

        prywatny StateManager ()

        {

        }

        publiczna statyczna instancja StateManager

        {

            dostać

            {

                return Nested.obj;

            }

        }

        klasa prywatna Zagnieżdżona

        {

            statyczne zagnieżdżone ()

            {

            }

            wewnętrzny statyczny tylko do odczytu StateManager obj = new StateManager ();

        }

    }

Oto leniwa implementacja StateManagerklasy, która wykorzystuje Lazyklasę. Możesz zobaczyć, jak Lazyzajęcia sprawiają, że wdrażanie lenistwa jest naprawdę proste. 

klasa publiczna StateManager

    {

        prywatne statyczne tylko do odczytu Lazy obj = new Lazy (() => new StateManager ());

        prywatny StateManager () {}

        publiczna statyczna instancja StateManager

        {

            dostać

            {

                return obj.Value;

            }

        }

    }

Spójrz na Instancenieruchomość w StateManagerpowyższej klasie. Zwróć uwagę, że Valuewłaściwość, którą widzisz w powyższym przykładzie kodu, jest tylko do odczytu. Z tego powodu nie ma ustawionego akcesorium.

Inicjalizacja z opóźnieniem to doskonała technika optymalizacji wydajności, umożliwiająca odroczenie inicjalizacji obiektów, które zużywają znaczne zasoby procesora i pamięci, dopóki nie będą absolutnie potrzebne. Skorzystaj z leniwej inicjalizacji, aby poprawić wydajność swoich aplikacji.