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 uncheckedClassificazione 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 versionsUso 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 CoreTrattamento 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 sprintVerifica 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
- Abilitazione e comprensione di NRT
- Annotazioni: ?, !, MaybeNull e NotNull
- Operatori null-conditional e null-coalescing
- Migrazione di una codebase a NRT