Condividi tramite


Risoluzione dei problemi relativi alle eccezioni: System.NullReferenceException

Un'eccezione NullReferenceException si verifica quando si cerca di usare un metodo o una proprietà di un tipo riferimento (C#, Visual Basic) il cui valore è null. Ad esempio, è possibile che si sia tentato di usare un oggetto senza prima specificare la parola chiave new (New in Visual Basic) oppure di usare un oggetto il cui valore è impostato su null (Nothing in Visual Basic).

Sezioni incluse in questo articolo

Classi usate in questo articolo

Cause più frequenti delle eccezioni NullReferenceException

Individuazione dell'origine delle eccezioni NullReferenceException durante lo sviluppo

Come evitare le eccezioni NullReferenceException

Gestione delle eccezioni NullReferenceException nel codice di rilascio

Classi usate in questo articolo

La maggior parte degli esempi inclusi in questo articolo usa una delle classi seguenti o entrambe:

public class Automobile
{
    public EngineInfo Engine {get; set;}
}

public class EngineInfo
{
    public EngineInfo() { }

    public EngineInfo(string powerSrc, double engineSize)
    {
        Power = powerSrc;
        Size = engineSize;
    }

    public double Size { get; set; }
    public string Power = null;
}
   
Public Class Automobile
    Public Property Engine As EngineInfo
End Class

Public Class EngineInfo
    Public Sub New()
    End Sub

    Public Sub New(powerSrc As String, engineSize As Double)
        Power = powerSrc
        Size = engineSize
    End Sub

    Public Property Size() As Double
    Public Power As String = Nothing
End Class

Torna all'inizioAltre sezioni incluse in questo articolo

Cause più frequenti delle eccezioni NullReferenceException

Qualsiasi variabile di tipo riferimento può essere null. Le variabili locali, le proprietà di una classe, i parametri di metodi e i valori restituiti dei metodi possono tutti contenere un riferimento null. Se si chiamano metodi o proprietà di queste variabili quando hanno valore null, viene generata un'eccezione NullReferenceException. Casi specifici:

Una variabile locale o un campo membro viene dichiarato ma non inizializzato

Una proprietà o un campo è null

Un parametro di un metodo è null

Il valore restituito di un metodo è null

Un oggetto in una raccolta o una matrice è null

Un oggetto non viene creato a causa di una condizione

Un oggetto passato per riferimento a un metodo è null

Una variabile locale o un campo membro viene dichiarato ma non inizializzato

Questo semplice errore è quello che si verifica più di frequente nel codice Visual Basic. Fatta eccezione per situazioni come la dichiarazione di una variabile da passare come parametro out, il compilatore C# non consente l'uso di una variabile di riferimento locale a meno che non venga inizializzata. Il compilatore Visual Basic genera un avviso.

  • Nel codice C# seguente, la riga evidenziata genera questo errore del compilatore:

Uso della variabile locale non assegnata 'engine'

  • Nel codice Visual Basic la riga evidenziata genera l'avviso del compilatore BC42104:

La variabile 'engine' viene usata prima che le sia stato assegnato un valore.  È possibile che venga restituita un'eccezione di riferimento null al runtime.

La riga, inoltre, genera un'eccezione NullReferenceException all'esecuzione.
public void NullReferencFromUninitializedLocalVariable()
{
    EngineInfo engine;
    Console.WriteLine(engine.ToString());
}
Public Sub NullReferencFromUninitializedLocalVariable()
    Dim engine As EngineInfo
    Console.WriteLine(engine.ToString())
End Sub

Torna all'inizioVoci incluse in questa sezione

Torna all'inizioSezioni incluse in questo articolo

Una proprietà o un campo è null

I campi e le proprietà di una classe vengono inizializzati automaticamente sul valore predefinito quando la classe viene creata. Il valore predefinito di un tipo riferimento è null (Nothing in Visual Basic). Se si chiamano metodi membro su un campo o una proprietà di una classe padre quando il valore del campo o della proprietà è null, viene generata un'eccezione NullReferenceException.

In questo esempio la riga evidenziata genera un'eccezione NullReferenceException perché la proprietà Engine di car è inizializzata automaticamente su null.

public void NullReferenceFromProperty()
{
    var car = new Automobile();

    Console.WriteLine(car.Engine.ToString());
}
Public Sub NullReferenceFromProperty()
    Dim car = New Automobile()
    Console.WriteLine(car.Engine.ToString())
End Sub

Torna all'inizioVoci incluse in questa sezione

Torna all'inizioSezioni incluse in questo articolo

Un parametro di un metodo è null

Un parametro di un metodo che è un tipo riferimento può essere null (Nothing in Visual Basic). Se si chiamano metodi o proprietà membri su un valore di parametro null viene generata un'eccezione NullReferenceException.

In questo esempio la riga evidenziata genera un'eccezione NullReferenceException perché BadEngineInfoPassedToMethod chiama NullReferenceFromMethodParameter con un parametro null.

public void BadEngineInfoPassedToMethod()
{
    EngineInfo eng = null;
    NullReferenceFromMethodParameter(eng);
}

public void NullReferenceFromMethodParameter(EngineInfo engine)
{
    Console.WriteLine(engine.ToString());
}
Public Sub BadParameterPassedToMethod() As EngineInfo
    Dim eng As EngineInfo = Nothing
    NullReferenceFromMethodParameter(eng)
End Sub

Public Sub NullReferenceFromMethodParameter(engine As EngineInfo)
    Console.WriteLine(engine.ToString())
End Sub

Torna all'inizioVoci incluse in questa sezione

Torna all'inizioSezioni incluse in questo articolo

Il valore restituito di un metodo è null

Un metodo che restituisce un tipo riferimento può restituire null (Nothing in Visual Basic). Se si chiamano metodi o proprietà del tipo riferimento restituito, viene generata un'eccezione NullReferenceException quando il riferimento è null.

In questo esempio la riga evidenziata genera un'eccezione NullReferenceException perché la chiamata a BadGetEngineInfo restituisce un riferimento null nel metodo NullReferenceFromMethodParameter.

public EngineInfo BadGetEngineInfo()
{
    EngineInfo engine = null;
    return engine;
}

public void NullReferenceFromMethodReturnValue()
{
    var engine = BadGetEngineInfo();
    Console.WriteLine(engine.ToString());
}
Public Function BadGetEngineInfo() As EngineInfo
    Dim engine As EngineInfo = Nothing
    Return engine
End Function

Public Sub NullReferenceFromMethodReturnValue()
    Dim engine = BadGetEngineInfo()
    Console.WriteLine(engine.ToString())
End Sub

Torna all'inizioVoci incluse in questa sezione

Torna all'inizioSezioni incluse in questo articolo

Un oggetto in una raccolta o una matrice è null

Un elenco o una matrice di tipi riferimento può contenere un elemento null. Se si chiamano metodi o proprietà di un elemento elenco null viene generata un'eccezione NullReferenceException.

In questo esempio la riga evidenziata in NullReferenceFromListItem() genera un'eccezione NullReferenceException perché la chiamata di BadGetCarList restituisce un elemento null.

public Automobile[] BadGetCarList()
{
    var autos = new Automobile[10];
    for (int i = 0; i autos.Length; i++)
    {
        if (i != 6)
        {
            autos[i] = new Automobile();
        }
    }
    return autos;
}

public void NullReferenceFromListItem()
{
    var cars = BadGetCarList();
    foreach (Automobile car in cars)
    {
        Console.WriteLine(car.ToString());
    }
}
Public Function BadGetCarList() As Automobile()
    Dim autos = New Automobile(10) {}
    For i As Integer = 0 To 9
        If i <> 6 Then
            autos(i) = New Automobile()
        End If
    Next
    Return autos
End Function

Public Sub NullReferenceFromListItem()
    Dim cars = BadGetCarList()
    For Each car As Automobile In cars
        Console.WriteLine(car.ToString())
    Next
End Sub

Torna all'inizioVoci incluse in questa sezione

Torna all'inizioSezioni incluse in questo articolo

Un oggetto non viene creato a causa di una condizione

Se un tipo riferimento viene inizializzato in un blocco condizionale, l'oggetto non viene creato quando la condizione ha valore false.

In questo esempio la riga evidenziata in NullReferenceFromConditionalCreation genera un'eccezione NullReferenceException perché inizializza la variabile engine solo se il metodo DetermineTheCondition() restituisce true.

 public bool DetermineTheCondition()
{
    return false;
}

public void NullReferenceFromConditionalCreation()
{
    EngineInfo engine = null;
    var condition = DetermineTheCondition();
    if (condition)
    {
        engine = new EngineInfo();
        engine.Power = "Diesel";
        engine.Size = 2.4;
    }
    Console.WriteLine(engine.Size);
}
Public Function DetermineTheCondition() As Boolean
    Return False
End Function

Public Sub NullReferenceFromConditionalCreation()
    Dim engine As EngineInfo = Nothing
    Dim condition = DetermineTheCondition()
    If condition Then
        engine = New EngineInfo()
        engine.Power = "Diesel"
        engine.Size = 2.4
    End If
    Console.WriteLine(engine.Size)
End Sub

Torna all'inizioVoci incluse in questa sezione

Torna all'inizioSezioni incluse in questo articolo

La proprietà di un oggetto passato a un metodo è impostata su null

Quando un oggetto viene passato come parametro a un metodo in base al valore (senza usare la parola chiave ref o out in C# o la parola chiave ByRef in Visual Basic), il metodo non è in grado di cambiare la posizione di memoria del parametro, ovvero la posizione a cui punta il parametro, ma può modificare le proprietà dell'oggetto.

In questo esempio il metodo NullPropertyReferenceFromPassToMethod crea un oggetto Automobile e inizializza la proprietà Engine. Chiama quindi BadSwapCarEngine passando il nuovo oggetto come parametro. BadSwapCarEngine imposta la proprietà Engine su null, motivo per cui la riga evidenziata in NullPropertyReferenceFromPassToMethod genera un'eccezione NullReferenceException.

public void BadSwapCarEngine(Automobile car)
{
    car.Engine = null;
}

public void (Automobile car)
{
    car.Engine = new EngineInfo("GAS", 1.5);
    BadSwapCarEngine(car);
    Console.WriteLine(car.Engine.ToString());
}
Public Sub BadSwapCarEngine(car As Automobile)
    car.Engine = Nothing
End Sub

Public Sub NullPropertyReferenceFromPassToMethod()
    Dim car As New Automobile()
    car.Engine = New EngineInfo("GAS", 1.5)
    BadSwapCarEngine(car)
    Console.WriteLine(car.Engine.ToString())
End Sub

Torna all'inizioVoci incluse in questa sezione

Torna all'inizioSezioni incluse in questo articolo

Un oggetto passato per riferimento a un metodo è null

Quando si passa un tipo riferimento come parametro a un metodo per riferimento (usando la parola chiave ref o out in C# o la parola chiave ByRef in Visual Basic), è possibile modificare la posizione di memoria a cui punta il parametro.

Se si passa un tipo riferimento per riferimento a un metodo, il metodo può impostare il tipo referenziato su null (Nothing in Visual Basic).

In questo esempio la riga evidenziata in NullReferenceFromPassToMethodByRef genera un'eccezione NullReferenceException perché la chiamata al metodo BadEngineSwapByRef imposta la variabile stockEngine su null.

public void BadEngineSwapByRef(ref EngineInfo engine)
{
    engine = null;
}

public void NullReferenceFromPassToMethodByRef()
{
    var stockEngine = new EngineInfo();
    stockEngine.Power = "Gas";
    stockEngine.Size = 7.0;
    BadSwapEngineByRef(ref stockEngine);
    Console.WriteLine(stockEngine.ToString());
}
Public Sub BadSwapEngineByRef(ByRef engine As EngineInfo)
    engine = Nothing
End Sub

Public Sub NullReferenceFromPassToMethodByRef()
    Dim formatStr = "The stock engine has been replaced by a {0} liter {} engine"
    Dim stockEngine = New EngineInfo()
    stockEngine.Power = "Gas"
    stockEngine.Size = 7.0
    BadSwapEngineByRef(stockEngine)
    Console.WriteLine(stockEngine.ToString())
End Sub

Torna all'inizioVoci incluse in questa sezione

Torna all'inizioSezioni incluse in questo articolo

Individuazione dell'origine di un'eccezione dovuta a un riferimento Null durante lo sviluppo

Usare i suggerimenti dati, la finestra Variabili locali e le finestre Espressioni di controllo per visualizzare i valori delle variabili

Analizzare lo stack di chiamate per individuare il punto in cui una variabile di riferimento non è inizializzata o è impostata su null

Impostare punti di interruzione condizionali per arrestare il debug quando un oggetto è null (Nothing in Visual Basic)

Usare i suggerimenti dati, la finestra Variabili locali e le finestre Espressioni di controllo per visualizzare i valori delle variabili

  • Posizionare il puntatore sul nome della variabile per visualizzarne il valore in un suggerimento dati. Se la variabile fa riferimento a un oggetto o una raccolta, è possibile espandere il tipo di dati per esaminare le proprietà o gli elementi.

  • Aprire la finestra Variabili locali per esaminare tutte le variabili attive nel contesto corrente.

  • Usare una finestra Espressioni di controllo per vedere come una variabile cambia mentre si esegue il codice un'istruzione alla volta.

Torna all'inizioVoci incluse in questa sezione

Torna all'inizioSezioni incluse in questo articolo

Analizzare lo stack di chiamate per individuare il punto in cui una variabile di riferimento non è inizializzata o è impostata su null

La finestra Stack di chiamate di Visual Studio visualizza un elenco di nomi dei metodi non completati quando il debugger si arresta in corrispondenza di un'eccezione o un punto di interruzione. È possibile selezionare un nome nella finestra Stack di chiamate e scegliere Passa al frame per cambiare il contesto di esecuzione del metodo ed esaminarne le variabili.

Torna all'inizioVoci incluse in questa sezione

Torna all'inizioSezioni incluse in questo articolo

Impostare punti di interruzione condizionali per arrestare il debug quando un oggetto è null (Nothing in Visual Basic)

È possibile impostare un punto di interruzione condizionale in modo da interrompere l'esecuzione quando una variabile è null. I punti di interruzione condizionali possono essere utili quando il riferimento Null non ricorre spesso, ad esempio quando un elemento in una raccolta è null solo a intermittenza. Un altro vantaggio dei punti di interruzione condizionali è che consentono di eseguire il debug di un problema prima del commit in una determinata routine di gestione.

Torna all'inizioVoci incluse in questa sezione

Torna all'inizioSezioni incluse in questo articolo

Come evitare le eccezioni NullReferenceException

Usare Debug.Assert per confermare un'invariabile

Inizializzare completamente i tipi riferimento

Usare Debug.Assert per confermare un'invariabile

Un invariante è una condizione che restituisce sempre true. Un'istruzione Debug.Assert (System.Diagnostics) viene chiamata solo dalle build di debug delle app e non da codice di rilascio. Se la condizione dell'invariabile non è true, il debugger si interrompe in corrispondenza dell'istruzione Assert e visualizza un finestra di dialogo. Debug.Assert verifica che la condizione non sia cambiata durante lo sviluppo dell'app. Un'asserzione indica anche ad altri utenti che leggono il codice che la condizione deve essere sempre true.

Ad esempio, il metodo MakeEngineFaster presuppone che il parametro engine non sarà mai null perché il relativo metodo OnlyCaller (TheOnlyCallerOfMakeEngineFaster) inizializza sempre completamente EngineInfo. L'asserzione in MakeEngineFaster documenta questo presupposto e verifica che sia true.

Se un utente aggiunge un nuovo metodo caller (BadNewCallerOfMakeEngineFaster) che non inizializza il parametro, viene attivata l'asserzione.

private void TheOnlyCallerOfMakeEngineFaster()
{
    var engine = new EngineInfo();
    engine.Power = "GAS";
    engine.Size = 1.5;
    MakeEngineFaster(engine);
}

private void MakeEngineFaster(EngineInfo engine)
{
    System.Diagnostics.Debug.Assert(engine != null, "Assert: engine != null");
    engine.Size *= 2;
    Console.WriteLine("The engine is twice as fast");
}

private void BadNewCallerOfMakeEngineFaster()
{
    EngineInfo engine = null;
    MakeEngineFaster(engine);
}
Public Sub TheOnlyCallerOfMakeEngineFaster()
    Dim engine As New EngineInfo
    engine.Power = "GAS"
    engine.Size = 1.5
    MakeEngineFaster(engine)
End Sub

Private Sub MakeEngineFaster(engine As EngineInfo)
    System.Diagnostics.Debug.Assert(engine IsNot Nothing, "Assert: engine IsNot Nothing")
    engine.Size = engine.Size * 2
    Console.WriteLine("The engine is twice as fast")
End Sub

Public Sub BadNewCallerOfMakeEngineFaster()
    Dim engine As EngineInfo = Nothing
    MakeEngineFaster(engine)
End Sub

Torna all'inizioVoci incluse in questa sezione

Torna all'inizioSezioni incluse in questo articolo

Inizializzare completamente i tipi riferimento

Per limitare le eccezioni NullReferenceException, inizializzare completamente i tipi riferimento subito dopo la creazione.

Aggiungere l'inizializzazione completa alle classi personalizzate

Se si ha il controllo della classe che genera un'eccezione NullReferenceException, è consigliabile inizializzare completamente l'oggetto nel costruttore del tipo. Ecco ad esempio una versione rivista delle classi di esempio che garantisce l'inizializzazione completa:

public class Automobile
{
    public EngineInfo Engine { get; set; }

    public Automobile() 
    { 
        this.Engine = new EngineInfo(); 
    }

    public Automobile(string powerSrc, double engineSize)
    {
        this.Engine = new EngineInfo(powerSrc, engineSize);
    }
}


public class EngineInfo
{
    public double Size {get; set;}
    public string Power {get; set;}

    public EngineInfo() 
    { 
        // the base engine 
        this.Power = "GAS"; 
        this.Size = 1.5; 
    }

    public EngineInfo(string powerSrc, double engineSize)
    {
        this.Power = powerSrc;
        this.Size = engineSize;
    }
}
Public Class Automobile
    Public Property Engine As EngineInfo

    Public Sub New() 
        Me.Engine = New EngineInfo() 
    End Sub 

    Public Sub New(powerSrc As String, engineSize As Double) 
        Me.Engine = New EngineInfo(powerSrc, engineSize) 
    End Sub

End Class

Public Class BaseEngineInfo
    Public Sub New() 
        ' the base engine 
        Me.Power = "GAS" 
        Me.Size = 1.5 
    End Sub

    Public Sub New(powerSrc As String, engineSize As Double)
        Power = powerSrc
        Size = engineSize
    End Sub

    Public Property Size() As Double
    Public Power As String = String.Empty
End Class

Nota

Usare l'inizializzazione differita per proprietà di grandi dimensioni o usate di rado

Per ridurre il footprint di memoria della classe e aumentarne le prestazioni, è consigliabile usare l'inizializzazione differita delle proprietà dei tipi riferimento.Vedere Inizializzazione differita.

Gestione delle eccezioni NullReferenceException nel codice di rilascio

Verificare se sono presenti valori null (Nothing in Visual Basic) prima di usare un tipo riferimento

Usare try – catch – finally (Try – Catch – Finally in Visual Basic) per gestire l'eccezione

È meglio evitare un'eccezione NullReferenceException piuttosto che gestirla dopo che si è verificata. La gestione di un'eccezione può complicare la gestione e la comprensione del codice e può talvolta introdurre altri bug. Un'eccezione NullReferenceException è spesso un errore irreversibile. In questi casi, lasciare che l'eccezione arresti l'app potrebbe essere l'alternativa migliore.

In diverse situazioni, tuttavia, la gestione dell'errore può essere utile:

  • L'app può ignorare gli oggetti null. Ad esempio, se l'app recupera ed elabora i record di un database, potrebbe essere possibile ignorare alcuni record che risultano in oggetti null. Potrebbe essere sufficiente registrare i dati errati in un file di log o nell'interfaccia utente dell'applicazione.

  • È possibile ripristinare lo stato precedente l'eccezione. Ad esempio, una chiamata a un servizio Web che restituisce un tipo riferimento potrebbe restituire null in caso di perdita o timeout della connessione. È possibile tentare di ristabilire la connessione e ripetere la chiamata.

  • È possibile ripristinare uno stato valido dell'app. Supponiamo ad esempio di dover eseguire un'attività in più passaggi che richiede di salvare le informazioni in un archivio dati prima di chiamare un metodo che genera un'eccezione NullReferenceException. Se l'oggetto non inizializzato dovesse danneggiare il record di dati, è possibile rimuovere i dati precedenti prima di chiudere l'app.

  • È consigliabile segnalare l'eccezione. Ad esempio, se l'errore è stato causato da un errore dell'utente dell'app, è possibile generare un messaggio che lo aiuti a fornire le informazioni corrette. È anche possibile registrare le informazioni sull'errore per agevolare la risoluzione del problema. Alcuni framework, come ASP.NET, hanno un gestore di eccezioni di alto livello che acquisisce tutti gli errori in modo tale che non si verifichino mai arresti anomali dell'app. In tal caso, la registrazione dell'eccezione potrebbe essere l'unico modo per sapere se si verifica effettivamente.

Ci sono due modi per gestire le eccezioni NullReferenceException nel codice di rilascio.

Verificare se sono presenti valori null (Nothing in Visual Basic) prima di usare un tipo riferimento

L'uso di un test esplicito per verificare che un oggetto non sia null prima di usarlo evita i problemi di prestazioni causati dai costrutti try-catch-finally. È comunque necessario determinare e implementare l'azione da eseguire in risposta all'oggetto non inizializzato.

In questo esempio CheckForNullReferenceFromMethodReturnValue testa il valore restituito del metodo BadGetEngineInfo. Se l'oggetto non è null, viene usato, altrimenti il metodo segnala l'errore.

public EngineInfo BadGetEngineInfo()
{
    EngineInfo engine = null;
    return engine;
}

public void CheckForNullReferenceFromMethodReturnValue()
{
    var engine = BadGetEngineInfo();
    if(engine != null)
    {
        // modify the info
        engine.Power = "DIESEL";
        engine.Size = 2.4;
    }
    else
    {
        // report the error
        Console.WriteLine("BadGetEngine returned null")
    }
}
public EngineInfo BadGetEngineInfo()
{
    EngineInfo engine = null;
    return engine;
}
Public Sub CheckForNullReferenceFromMethodReturnValue()
    Dim engine = BadGetEngineInfo()
    If (engine IsNot Nothing) Then
        ' modify the info
        engine.Power = "DIESEL"
        engine.Size = 2.4
    Else
        ' report the error
        Console.WriteLine("BadGetEngineInfo returned Nothing")
    End If

End Sub

Torna all'inizioVoci incluse in questa sezione

Torna all'inizioSezioni incluse in questo articolo

Usare try–catch–finally (Try–Catch–Finally in Visual Basic) per gestire l'eccezione

L'uso dei costrutti di gestione delle eccezioni incorporati (try, catch, finally in C#, Try, Catch, Finally in Visual Basic) offre più opzioni per la gestione delle eccezioni NullReferenceException rispetto alla semplice verifica se un oggetto non è null.

In questo esempio, CatchNullReferenceFromMethodCall usa due asserzioni per verificare il presupposto che il relativo parametro contiene un'automobile completa, incluso un motore. Nel blocco try, la riga evidenziata genera un'eccezione NullReferenceException perché la chiamata a RarelyBadEngineSwap può distruggere la proprietà Engine dell'automobile. Il blocco catch acquisisce l'eccezione, scrive le informazioni sull'eccezione in un file e segnala l'errore all'utente. Nel blocco finally, il metodo verifica che lo stato dell'automobile non sia peggiore rispetto a quando il metodo è iniziato.

public void RarelyBadSwapCarEngine(Automobile car)
{
    if ((new Random()).Next() == 42)
    {
        car.Engine = null;
    }
    else
    {
        car.Engine = new EngineInfo("DIESEL", 2.4);
    }
}

public void CatchNullReferenceFromMethodCall(Automobile car)
{
    System.Diagnostics.Debug.Assert(car != null, "Assert: car != null");
    System.Diagnostics.Debug.Assert(car.Engine != null, "Assert: car.Engine != null");

    // save current engine properties in case they're needed
    var enginePowerBefore = car.Engine.Power;
    var engineSizeBefore = car.Engine.Size;

    try
    {
        RarelyBadSwapCarEngine(car);
        var msg = "Swap succeeded. New engine power source: {0} size {1}";
        Console.WriteLine(msg, car.Engine.Power, car.Engine.Size);
    }
    catch(NullReferenceException nullRefEx)
    {
        // write exception info to log file
        LogException(nullRefEx);
        // notify the user
        Console.WriteLine("Engine swap failed. Please call your customer rep.");
    }
    finally
    {
        if(car.Engine == null)
        {
            car.Engine = new EngineInfo(enginePowerBefore, engineSizeBefore);
        }
    }
}
Public Sub RarelyBadSwapCarEngine(car As Automobile)
    If (New Random()).Next = 42 Then
        car.Engine = Nothing
    Else
        car.Engine = New EngineInfo("DIESEL", 2.4)
    End If
End Sub

Public Sub CatchNullReferenceFromMethodCall(car As Automobile)
    System.Diagnostics.Debug.Assert(car IsNot Nothing)
    System.Diagnostics.Debug.Assert(car.Engine IsNot Nothing)

    ' save current engine properties in case they're needed
    Dim powerBefore = car.Engine.Power
    Dim sizeBefore = car.Engine.Size

    Try
        RarelyBadSwapCarEngine(car)
        Dim msg = "Swap succeeded. New engine power source: {0} size {1}"
        Console.WriteLine(msg, car.Engine.Power, car.Engine.Size)
    Catch nullRefEx As NullReferenceException
        ' write exception info to log file
        LogException(nullRefEx)
        ' notify user
        Console.WriteLine("Engine swap failed. Please call your customer rep.")
    Finally
        If car.Engine Is Nothing Then car.Engine = New EngineInfo(powerBefore, sizeBefore)
    End Try

End Sub

Torna all'inizioVoci incluse in questa sezione

Torna all'inizioSezioni incluse in questo articolo

Articoli correlati

Linee guida di progettazione delle eccezioni (Linee guida per la progettazione di .NET Framework)

Gestione e generazione di eccezioni (Concetti di base sulle applicazioni .NET Framework)

Procedura: Ricevere notifiche di eccezioni first-chance (Guida di sviluppo per .NET Framework)

Procedura: Gestire le eccezioni in una query PLINQ (Guida di sviluppo per .NET Framework)

Eccezioni in thread gestiti (Guida di sviluppo per .NET Framework)

Eccezioni e gestione delle eccezioni (Guida per programmatori C#)

Istruzioni di gestione delle eccezioni (Riferimenti per C#)

.Istruzione Try...Catch...Finally (Visual Basic)

Gestione delle eccezioni (F#)

Eccezioni in C++/CLI

Gestione delle eccezioni (Task Parallel Library)

Gestione delle eccezioni (debug)

Procedura dettagliata: Gestione di un'eccezione di concorrenza (Accesso ai dati in Visual Studio)

Procedura: Gestire gli errori e le eccezioni che si verificano con il data binding (Windows Forms)

Gestione di eccezioni nelle app di rete (XAML) (Windows)

Torna all'inizioSezioni incluse in questo articolo