loading experience

C#

Primary constructors in C#: quando usarli e quando no

Meno codice ripetitivo nelle classi di servizio, ma con qualche trappola da conoscere.

Primary constructors in C#: quando usarli e quando no

Dal C# 12 le classi possono avere un costruttore primario: i parametri si dichiarano accanto al nome della classe e sono visibili in tutto il corpo. Sono perfetti per i servizi con dependency injection.

Comodi per i servizi, da usare con qualche cautela.
Comodi per i servizi, da usare con qualche cautela.

Prima e dopo

// Prima
public class OrdiniService
{
    private readonly IOrdiniRepository _repo;
    private readonly ILogger<OrdiniService> _log;

    public OrdiniService(IOrdiniRepository repo, ILogger<OrdiniService> log)
    {
        _repo = repo;
        _log = log;
    }
}

// Con il costruttore primario
public class OrdiniService(IOrdiniRepository repo, ILogger<OrdiniService> log)
{
    public async Task<Ordine?> CercaAsync(int id)
    {
        log.LogInformation("Cerco l'ordine {Id}", id);
        return await repo.TrovaAsync(id);
    }
}

La trappola: i parametri non sono readonly

Un parametro del costruttore primario è modificabile dentro la classe. Se vuoi la garanzia che non cambi, assegnalo a un campo readonly:

public class Cache(TimeSpan durata)
{
    private readonly TimeSpan _durata = durata;
}

Altre attenzioni

  • Non usare lo stesso parametro sia direttamente sia per inizializzare un campo: il compilatore avvisa perché si creerebbero due copie dello stato.
  • Per i tipi che rappresentano dati, i record restano la scelta migliore: generano proprietà, uguaglianza e ToString.
  • Se il costruttore deve validare i parametri, una validazione nell'inizializzatore di un campo funziona, ma per logica complessa un costruttore classico è più chiaro.
Commenti (0)

Nessun commento ancora.

Lascia un commento