Comment effectuer une initialisation différée en C #

L'initialisation paresseuse est une technique qui reporte la création d'un objet jusqu'à la première fois qu'elle est nécessaire. En d'autres termes, l'initialisation de l'objet se produit uniquement à la demande. Notez que les termes initialisation paresseuse et instanciation paresseuse signifient la même chose: ils peuvent être utilisés de manière interchangeable. En tirant parti de l'initialisation tardive, vous pouvez améliorer les performances de l'application en évitant les calculs inutiles et la consommation de mémoire. Dans cet article, nous verrons comment nous pouvons effectuer une initialisation différée en C #.

Comprenons le chargement paresseux avec un exemple simple. Considérez deux classes, Customeret Order. La Customerclasse contient une Orderspropriété qui à son tour fait référence à une collection d'instances de la Orderclasse. La Orderscollection peut contenir une grande quantité de données et peut même nécessiter une connexion à la base de données pour se connecter à la base de données et récupérer des enregistrements. Dans un tel cas, il est inutile de charger des données dans la Orderspropriété tant que nous n'avons pas besoin des données. L'initialisation paresseuse nous permet de charger la Orderscollection uniquement lorsque les données sont demandées.

Utilisation de la classe Lazy en C #

Bien que vous puissiez écrire votre propre code personnalisé pour implémenter l'initialisation différée, Microsoft vous recommande d'utiliser la Lazyclasse à la place. La Lazyclasse dans l' Systemespace de noms en C # a été introduite dans le cadre de .Net Framework 4.0 pour fournir un moyen sûr pour les threads d'implémenter l'initialisation différée. Vous pouvez profiter de cette classe pour différer l'initialisation des objets gourmands en ressources dans votre application.

Lorsque vous utilisez la Lazyclasse, vous devez spécifier le type d'objet que vous avez l'intention de créer paresseusement dans l'argument type. Notez que l'initialisation tardive se produit lorsque vous accédez à la Lazy.Valuepropriété. Voici un exemple de la façon dont la Lazyclasse peut être utilisée:

Paresseux
   
     commandes = nouveau Lazy
    
     ();
     

IEnumerable result = lazyOrders.Value;

Maintenant, considérons deux classes, Authoret Blog. Un auteur peut écrire de nombreux articles de blog, vous avez donc une relation un-à-plusieurs entre les classes Authoret Blog, comme indiqué dans l'extrait de code ci-dessous.

public class Auteur

    {

        public int Id {get; ensemble; }

        chaîne publique FirstName {get; ensemble; }

        chaîne publique LastName {get; ensemble; }

        chaîne publique Address {get; ensemble; }

        Liste des blogs publics {get; ensemble; }

    }

    Blog de classe publique

    {

        public int Id {get; ensemble; }

        chaîne publique Title {get; ensemble; }

        public DateTime PublicationDate {get; ensemble; }

    }

Notez que la relation un-à-plusieurs entre les classes Authoret Bloga été représentée à l'aide d'une Listpropriété (de type Blog) dans la Authorclasse. En utilisant cette propriété, la Authorclasse peut contenir une collection d'une ou plusieurs instances de la Blogclasse.

Supposons maintenant que nous ayons besoin d'afficher uniquement les détails d'un auteur (prénom, nom et adresse) dans l'interface utilisateur. Il ne sert à rien de charger les détails du blog pour l'auteur dans ce cas; nous voulons charger les détails du blog paresseusement. Voici la Authorclasse mise à jour qui répond à ce besoin. Notez l'utilisation de la Lazyclasse.

public class Auteur

    {

        public int Id {get; ensemble; }

        chaîne publique FirstName {get; ensemble; }

        chaîne publique LastName {get; ensemble; }

        chaîne publique Address {get; ensemble; }

        public paresseux Blogs => nouveau Lazy (() => GetBlogDetailsForAuthor (this.Id));

        IList privé GetBlogDetailsForAuthor (ID int)

        {

       // Écrivez le code ici pour récupérer tous les détails du blog pour un auteur.

        }

    }

Utilisation de la classe Lazy générique en C #

Voyons maintenant comment nous pouvons tirer parti d'une Lazyclasse générique pour implémenter le modèle de conception Singleton. (Vous pouvez lire mon article sur le modèle de conception Singleton ici.) La version suivante de la StateManagerclasse est thread-safe. En même temps, il démontre une initialisation paresseuse. Notez que le constructeur statique explicite a été utilisé pour garantir que le compilateur C # ne marque pas le type comme beforefieldinit.

classe scellée publique StateManager

    {

        StateManager privé ()

        {

        }

        Instance publique statique de StateManager

        {

            avoir

            {

                return Nested.obj;

            }

        }

        classe privée imbriquée

        {

            statique imbriqué ()

            {

            }

            statique interne en lecture seule StateManager obj = new StateManager ();

        }

    }

Voici une implémentation paresseuse de la StateManagerclasse qui exploite la Lazyclasse. Vous pouvez voir comment la Lazyclasse simplifie la mise en œuvre de la paresse. 

classe publique StateManager

    {

        statique privé en lecture seule Lazy obj = new Lazy (() => new StateManager ());

        StateManager privé () {}

        Instance publique statique de StateManager

        {

            avoir

            {

                return obj.Value;

            }

        }

    }

Jetez un œil à la Instancepropriété dans la StateManagerclasse ci-dessus. Notez que la Valuepropriété que vous voyez dans l'exemple de code ci-dessus est en lecture seule. Pour cette raison, il n'y a pas d'accesseur défini.

L'initialisation paresseuse est une excellente technique d'optimisation des performances, vous permettant de différer l'initialisation des objets qui consomment des ressources CPU et mémoire importantes jusqu'à ce que vous en ayez absolument besoin. Tirez parti de l'initialisation paresseuse pour améliorer les performances de vos applications.