0Pricing
C# Academy · Lezione

Migrazione di una codebase a NRT

Applichi una strategia di migrazione graduale: abiliti gli avvisi, annoti le API, risolva i problemi ed eviti i falsi positivi.

Migrazione di una codebase a NRT è una lezione C# Academy gratuita su CoddyKit. Questa è la lezione 4 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento C# Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso C# Academy include 4 lezioni in totale.

La sfida della migrazione

L'abilitazione di NRT in una codebase esistente produce in genere centinaia di avvisi. Un approccio tutto e subito è rischioso. È preferibile una migrazione per fasi: abilitare gli avvisi gradualmente, correggerli file per file e mantenere costante il ritmo.

Passaggio 1: abilitare solo gli avvisi

Iniziare con <Nullable>warnings</Nullable> invece di enable. In questo modo si attivano gli avvisi senza trattare il codice non annotato come codice contenente errori: è un punto di partenza sicuro.

<!-- Phase 1: warnings only, no breaking change -->
<PropertyGroup>
  <Nullable>warnings</Nullable>
</PropertyGroup>

<!-- Phase 2: full enable per file as you migrate -->
<!-- Phase 3: switch to enable globally when done -->

Passaggio 2: abilitare file per file

Aggiungere #nullable enable all'inizio di ogni file mentre vi si lavora. In questo modo le modifiche restano limitate ai file in fase di modifica e le revisioni diventano più gestibili.

#nullable enable
// Now this file has full NRT analysis

public class OrderService
{
    private readonly IOrderRepository _repo;
    // Compiler now warns about uninitialized non-nullable fields,
    // unsafe dereferences, and assignment to non-nullable

    public OrderService(IOrderRepository repo) => _repo = repo;
}

// Other files without #nullable enable are still unchecked

Classificazione degli avvisi

Gli avvisi rientrano in due categorie: sopprimibili senza rischi (entità ORM, campi iniettati tramite DI) e veri bug (valori effettivamente null dereferenziati). È importante distinguerli prima di sopprimere qualsiasi avviso.

// Category 1: safe to suppress with null!
// EF Core navigation properties — set by EF, never null in practice
public class Order
{
    public Customer Customer { get; set; } = null!;
}

// Category 2: real bug — must fix
public string GetFullName()
{
    return FirstName + " " + LastName; // LastName was string? -- BUG!
}

Correzione dell'avviso del costruttore CS8618

CS8618 viene generato quando una proprietà non nullable non viene impostata nel costruttore. La correzione preferibile consiste nel renderla obbligatoria nel costruttore. Utilizzare = null! solo per i valori impostati dal framework.

// BEFORE (CS8618)
public class Product
{
    public string Name { get; set; }   // warning
    public Category Category { get; set; } // warning
}

// AFTER — constructor required:
public class Product
{
    public string Name { get; set; }
    public Category Category { get; set; }

    public Product(string name, Category category)
    {
        Name = name;
        Category = category;
    }
}

Gestione delle API legacy

Le API di terze parti o legacy potrebbero non essere annotate. I relativi tipi restituiti sono oblivious (né nullable né non-nullable). Assegnare i risultati a variabili nullable per rendere esplicito il comportamento.

// Legacy API returns 'string' but might be null (oblivious type)
string? legacyResult = OldLibrary.GetValue(); // store as nullable
if (legacyResult is null) return;

// Or convert at the boundary:
string safe = OldLibrary.GetValue() ?? "";

// For third-party types, check if they have NRT annotations:
// NuGet packages often add nullable annotations in newer versions

Uso di #pragma per sopprimere avvisi specifici

Quando un avviso è realmente un falso positivo e = null! risulta troppo rumoroso, utilizzare #pragma warning disable limitandolo alla riga specifica.

// Suppress for a specific case with explanation:
#pragma warning disable CS8618 // ORM populates this via reflection
public DbSet<Product> Products { get; set; }
#pragma warning restore CS8618

// Or inline with a comment:
public DbSet<Order> Orders { get; set; } = null!; // set by EF Core

Trattamento degli avvisi NRT come errori

Una volta corretti tutti gli avvisi di un file, aggiungere <WarningsAsErrors>Nullable</WarningsAsErrors> (oppure applicare il controllo in CI) per prevenire regressioni: qualsiasi nuovo problema relativo ai valori nullable farà fallire la compilazione.

<!-- After full migration: treat nullable warnings as build errors -->
<PropertyGroup>
  <Nullable>enable</Nullable>
  <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
  <!-- Or selectively: -->
  <!-- <WarningsAsErrors>CS8600;CS8602;CS8603</WarningsAsErrors> -->
</PropertyGroup>

Annotazione delle API pubbliche

Quando altri utilizzano la libreria, le annotazioni NRT diventano parte del contratto della relativa API pubblica. Restituire T? quando il risultato può essere null; restituire T quando è garantito che non lo sia.

public interface IProductService
{
    // Contract: FindById MAY return null, GetById never does
    Product? FindById(int id);
    Product  GetById(int id);  // throws if not found

    // Collection: never null (may be empty)
    IReadOnlyList<Product> GetAll();

    // String: may be empty but not null
    string GetSummary(int id);
}

Metriche e monitoraggio della migrazione

Monitorare i progressi contando i file con #nullable enable oppure eseguendo dotnet build 2>&1 | grep CS86 in CI. Stabilire una data obiettivo per completare la migrazione dell'intero progetto.

# Count NRT warnings in current build
dotnet build 2>&1 | grep -c 'CS860[0-9]\|CS861[0-9]\|CS862[0-9]'

# List files still missing #nullable enable
grep -rL '#nullable enable' src/ --include='*.cs'

# Track in CI: fail if warning count increases
# Set a budget: warnings <= N, where N decreases each sprint

Verifica rapida

Che cosa comunica l'assegnazione = null! a una proprietà non nullable?

Riepilogo: migrazione a NRT

Punti chiave:

  • Utilizzare una migrazione per fasi: modalità avvisi → abilitazione file per file → abilitazione globale
  • Distinguere i veri bug (da correggere) dai pattern ORM/DI (per i quali utilizzare = null!)
  • Correggere CS8618 rendendo obbligatori i valori nei costruttori, non sopprimendo l'avviso
  • Assegnare i risultati delle API legacy a variabili T? per rendere esplicito il comportamento
  • Trattare gli avvisi nullable come errori in CI per prevenire regressioni
  • Le API pubbliche annotate diventano contratti chiari per chi le utilizza

Domande Frequenti

La lezione «Migrazione di una codebase a NRT» è gratuita?

Sì — il testo completo di «Migrazione di una codebase a NRT» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso C# Academy, passa a CoddyKit PRO. Il corso C# Academy include 4 lezioni in totale.

Cosa imparerò in «Migrazione di una codebase a NRT»?

Applichi una strategia di migrazione graduale: abiliti gli avvisi, annoti le API, risolva i problemi ed eviti i falsi positivi. Eserciti C# Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare C# Academy?

Non è richiesta alcuna esperienza precedente. C# Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 4 di 4.

Quanto tempo richiede la lezione «Migrazione di una codebase a NRT»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione C# Academy?

Sì. Ogni lezione C# Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Abilitazione e comprensione di NRT
  2. Annotazioni: ?, !, MaybeNull e NotNull
  3. Operatori null-conditional e null-coalescing
  4. Migrazione di una codebase a NRT
← Torna a C# Academy