CodeGym /Corsi /C# SELF /Analisi degli avvisi del compilatore

Analisi degli avvisi del compilatore

C# SELF
Livello 14 , Lezione 4
Disponibile

1. Introduzione

Immagina che il codice sia una pièce teatrale e le variabili siano gli attori. Ogni volta che una variabile entra in una nuova scena (blocco di codice), può essere "viva" (ha un valore) oppure un "fantasma" (null). Ma c'è un problema: lo spettatore — il compilatore — guarda la pièce non dal vivo, ma solo dal copione. Vede dove agli attori vengono assegnati i ruoli (valori), e dove spariscono (diventano null). Ma non può vedere la realtà (l'esecuzione del programma) — può solo immaginare in base al copione!

L'analisi statica del flusso dei dati è il processo in cui il compilatore controlla il codice prima che il programma venga eseguito, per capire se qualcuno sta per recitare la scena del "crollo NullReferenceException".

Il succo del processo

A partire da C# 8.0 e con l'arrivo della modalità Nullable Reference Types (NRT), il compilatore analizza se una variabile può diventare null in qualche ramo di esecuzione. E se sì — te lo dice subito. Non ti lascia "usare il nome di un attore che è diventato improvvisamente un fantasma".

2. Come leggere gli avvisi del compilatore

Categorie principali di avvisi

Quando la modalità NRT è attiva, il compilatore tiene d'occhio soprattutto le variabili di tipo reference (string, User, array, oggetti). Ecco i tipi di avvisi più comuni:

  • Possible null assignment — stai cercando di assegnare un valore che potrebbe essere null a una variabile che non lo accetta.
  • Dereference of a possibly null reference — stai accedendo a un membro di un oggetto, ma il compilatore non è sicuro che non sia null.
  • Possible null return — un metodo potrebbe restituire null anche se dalla firma dovrebbe restituire un valore.
  • Nullable object must have a value — stai usando .Value su un tipo nullable senza controllare prima.
  • Unassigned non-nullable property — non hai assegnato un valore a un campo/proprietà che non accetta null.

Di solito in IDE (tipo Rider o Visual Studio) questi avvisi sono sottolineati con una linea ondulata, e passando il mouse sopra compare una spiegazione.

Esempio di avviso tipico


#nullable enable

string? possibleNull = GetString();

// Ops, il compilatore si lamenta: "Dereference of a possibly null reference"
int length = possibleNull.Length; // Avviso!

Il compilatore non è sicuro che possibleNull sia diverso da null, quindi accedere a .Length potrebbe causare un'eccezione.

Se il metodo è così:

string? GetString() { ... }

E scrivi:

string nonNullable = GetString();

Riceverai un avviso: possibile assegnamento non sicuro di null a una variabile non-nullable.

3. Il compilatore analizza il tuo codice

Esempio 1: assegnamento diretto


string? name = null;
Console.WriteLine(name.Length); // Avviso: possibile accesso a null

Qui è ovvio: name è null, quindi provare ad accedere a una proprietà è potenzialmente pericoloso.

Esempio 2: controllo su null


string? name = GetUserName();

if (name != null)
{
    Console.WriteLine(name.Length); // Tutto ok!
}
else
{
    Console.WriteLine("Nome non specificato!");
}

Il compilatore capisce che dentro il blocco if (name != null) la variabile è sicura. Questo è il flow analysis — analisi del flusso dei valori in base alle condizioni.

4. Il compilatore non può guardare "dentro il metodo"

Guarda solo la firma — se c'è scritto che il metodo restituisce string?, crede che possa essere null, anche se dentro restituisce sempre una stringa.

Esempio 3: ritorno di un valore da un metodo


string? GetMaybeName(bool useName)
{
    if (useName)
        return "Code Jedi";
    else
        return null;
}

void PrintLength()
{
    string? name = GetMaybeName(false);

    Console.WriteLine(name.Length); // Avviso!
}

Il compilatore vede che GetMaybeName può restituire null, quindi ti chiede di stare attento.

5. Scenari comuni e avvisi

Assegnamento di nullable a variabile non-nullable


string? maybeUser = GetUser();
string alwaysUser = maybeUser; // warning: possible null assignment

Per eliminare l'avviso:


string alwaysUser = maybeUser ?? "Ospite";

Così ci sarà sempre una stringa — o dal metodo, o "Ospite".

Dimenticato di controllare .HasValue su un value-type nullable


int? age = GetAge();
int realAge = age.Value; // warning: possibile accesso a null

Devi fare così:


if (age.HasValue)
    Console.WriteLine(age.Value);

Oppure:


int realAge = age ?? -1;

Proprietà automatiche senza inizializzazione


class User
{
    public string Name { get; set; } // warning: non inizializzato!
}

Soluzioni:


public string Name { get; set; } = "Senza nome";

oppure


public string? Name { get; set; }

6. Casi complessi di analisi del flusso

Analisi nei cicli


string? text = null;

while (text == null)
{
    text = Console.ReadLine();
}

Console.WriteLine(text.Length); // tutto ok: il compilatore ha capito!

Diversi percorsi di assegnamento


string? name;
if (Random.Shared.Next() % 2 == 0)
    name = "Alice";
else
    name = null;

Console.WriteLine(name.Length); // warning: possible null dereference

Il compilatore analizza tutti i rami. Se anche in uno solo c'è null — ti avvisa.

7. Come "calmare" il compilatore (e quando non dovresti farlo)

A volte sei sicuro che il valore non può essere null, ma il compilatore non ti crede:


string? value = GetSomething();
if (value == null)
    throw new Exception("Valore atteso!");

Console.WriteLine(value.Length); // L'avviso sparisce

Oppure usi l'operatore !:


string? value = GetSomething();
Console.WriteLine(value!.Length); // Nessun avviso, ma potenzialmente pericoloso

Questo si chiama null-forgiving operator. Non controlla nulla — dice solo al compilatore: "tranquillo, è tutto sotto controllo". Ma se sbagli — a runtime becchi un'eccezione.

2
Compito
C# SELF, livello 14, lezione 4
Bloccato
Controllo di null prima di usare una variabile
Controllo di null prima di usare una variabile
2
Compito
C# SELF, livello 14, lezione 4
Bloccato
Eliminazione degli avvisi usando l'operatore di coalescenza null
Eliminazione degli avvisi usando l'operatore di coalescenza null
1
Sondaggio/quiz
Tipi Nullable, livello 14, lezione 4
Non disponibile
Tipi Nullable
Introduzione ai Nullable Reference Types
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION