Lazy Initialization in C#

La Lazy Initialization è una tecnica di programmazione che consiste nell’assegnare un valore a un oggetto solo quando è effettivamente necessario, ritardando la sua inizializzazione fino al momento in cui viene effettivamente utilizzato.
Lo scopo è ridurre il consumo di memoria e conseguentemente migliorare le prestazioni, soprattutto quando si lavora con oggetti di grandi dimensioni o costosi in termini di risorse.

Vantaggi

  1. Riduzione del consumo di memoria: Non vengono allocate risorse per gli oggetti non utilizzati, risparmiando memoria.
  2. Miglioramento delle prestazioni: L’allocazione e l’inizializzazione degli oggetti avviene solo quando è effettivamente necessario, riducendo il tempo di avvio dell’applicazione.
  3. Scalabilità: La Lazy Initialization può migliorare la scalabilità di un’applicazione, in quanto riduce il carico iniziale di risorse.

Limiti

  1. Overhead aggiuntivo: La classe Lazy<T> aggiunge un livello di astrazione, il che potrebbe causare un lieve overhead di prestazioni.
  2. Complessità del codice: La Lazy Initialization può rendere il codice più complesso e difficile da gestire, in particolare se è necessario garantire la sincronizzazione tra thread.
  3. Non adatto per scenari multi-thread: Sebbene la classe Lazy<T> supporti la sincronizzazione dei thread, potrebbe essere meno efficiente rispetto all’inizializzazione anticipata in scenari multi-thread ad alta concorrenza.
  4. Potenziali problemi di temporizzazione: La Lazy Initialization può causare problemi di temporizzazione se un oggetto viene inizializzato in un momento inaspettato o critico dell’esecuzione dell’applicazione.
  5. Difficoltà nel debugging: La Lazy Initialization può rendere il debugging più difficile, poiché l’inizializzazione degli oggetti avviene solo in determinati momenti, e potrebbe essere complicato individuare eventuali errori o eccezioni legate all’inizializzazione.

C#

In C#, è possibile utilizzare la classe Lazy<T> del namespace System per implementare la Lazy Initialization.
Il metodo principale è la property Value che permette di inizializzare l’oggetto, se non è mai stato fatto, oppure ritornare l’istanza se è già stata costruita in precedenza.
L’utilizzo è molto semplice:

// Utilizzo di Lazy Initialization per l'oggetto 'MyExpensiveObject'
Lazy<MyExpensiveObject> lazyObject = new Lazy<MyExpensiveObject>();
MyExpensiveObject expensiveObject = lazyObject.Value;

La classe fornisce anche un costruttore per creare l’oggetto tramite factory new Lazy<T>(Func<T> valueFactory) e una property booleana IsValueCreated per sapere se è stato mai costruito l’oggetto.

Esempio

In questo esempio, l’oggetto MyExpensiveObject viene inizializzato (quindi ne viene chiamato il costruttore) solo quando si accede alla proprietà Value dell’oggetto lazyObject. Successivamente, il valore viene messo in una cache all’interno dell’oggetto Lazy<T> stesso in modo che, nelle chiamate successive alla proprietà .Value, verrà restituito il valore memorizzato senza ulteriori chiamate al costruttore.

Questo permette di ridurre la memoria utilizzata sullo heap, in quanto l’oggetto MyExpensiveObject verrà allocato e inizializzato solo quando è effettivamente necessario.

// Utilizzo di Lazy Initialization per l'oggetto 'MyExpensiveObject'
Lazy<MyExpensiveObject> lazyObject = new Lazy<MyExpensiveObject>();

Console.WriteLine("Lazy object creato.");

// L'oggetto verrà inizializzato solo quando lo richiediamo esplicitamente
Console.WriteLine("Premi un tasto per inizializzare l'oggetto.");
Console.ReadKey();

MyExpensiveObject expensiveObject = lazyObject.Value;

Console.WriteLine("Oggetto inizializzato e pronto per l'uso.");

Console.WriteLine("Premi un tasto per accedere nuovamente all'oggetto.");
Console.ReadKey();
MyExpensiveObject expensiveObject2 = lazyObject.Value;
Console.WriteLine("Oggetto già inizializzato, nessuna nuova inizializzazione.\n");

class MyExpensiveObject
{
    public MyExpensiveObject()
    {
        Console.WriteLine("Inizializzazione dell'oggetto MyExpensiveObject...");
        // Simulazione di un'operazione costosa
        System.Threading.Thread.Sleep(2000);
        Console.WriteLine("Inizializzazione completata.");
    }
}

Indice

Share
Ultimi articoli

Codice Pragmatico

Contatti

Per informazioni, dubbi o consulenze non esitate a contattarmi.

Lascia un messaggio

Ricevi le ultime news

Iscrivi alla newsletter

Solo articoli interessanti, promesso ;)