Leggere in inglese

Condividi tramite


Esercitazione: Estendere l'app console C# ed eseguire il debug in Visual Studio (parte 2 di 2)

Nella parte 2 di questa serie di esercitazioni si approfondirà le funzionalità di compilazione e debug di Visual Studio necessarie per lo sviluppo giornaliero. Queste funzionalità includono la gestione di più progetti, debug e riferimento a pacchetti di terze parti. Esegui l'app console C# che hai creato nella Parte 1 di di questa esercitazioneed esplora alcune funzionalità dell'ambiente di sviluppo integrato (IDE) di Visual Studio. Questa esercitazione è la parte 2 di una serie di esercitazioni in due parti.

In questa esercitazione vengono completate le attività seguenti:

  • Aggiungere un secondo progetto.
  • Librerie di riferimento e aggiungere pacchetti.
  • Eseguire il debug del codice.
  • Ispeziona il codice completato.

Prerequisiti

Per eseguire questo articolo, è possibile usare una di queste app calcolatrice:

Aggiungere un altro progetto

Il codice reale prevede progetti che interagiscono tra loro in una soluzione. È possibile aggiungere un progetto di libreria di classi all'app calcolatrice che fornisce alcune funzioni di calcolatrice.

In Visual Studio si usa il comando di menu File>Aggiungi>Nuovo progetto per aggiungere un nuovo progetto. È anche possibile fare clic con il pulsante destro del mouse sulla soluzione in Esplora soluzioni per aggiungere un progetto dal menu di scelta rapida.

  1. In Esplora soluzioni fare clic con il pulsante destro del mouse sul nodo della soluzione e scegliere Aggiungi>Nuovo progetto.

  2. Nella finestra Aggiungi un nuovo progetto digitare libreria di classi nella casella di ricerca. Scegliere il modello di progetto della libreria di classi C# e quindi selezionare Avanti.

    Screenshot della selezione di un modello di progetto di libreria di classi.

  3. Nella schermata Configura il nuovo progetto digitare il nome del progetto CalculatorLibrarye quindi selezionare Avanti.

  4. Scegliere .NET 3.1 quando richiesto. Visual Studio crea il nuovo progetto e lo aggiunge alla soluzione.

    Screenshot di Esplora Soluzioni con aggiunto il progetto della libreria di classi CalculatorLibrary.

  5. Rinominare il file Class1.cs in CalculatorLibrary.cs. Per rinominare il file, è possibile fare clic con il pulsante destro del mouse sul nome in Esplora soluzioni e scegliere Rinomina, selezionare il nome e premere F2oppure selezionare di nuovo il nome e selezionare di nuovo per digitare.

    Un messaggio potrebbe chiedere se si desidera rinominare i riferimenti a Class1 nel file. Non importa come rispondere, perché il codice verrà sostituito in un passaggio futuro.

  6. Aggiungere ora un riferimento al progetto, in modo che il primo progetto possa usare le API esposte dalla nuova libreria di classi. Fare clic con il pulsante destro del mouse sul nodo Dipendenze nel progetto Calcolatrice e scegliere Aggiungi riferimento al progetto.

    Screenshot della voce di menu Aggiungi riferimento al progetto.

    Viene visualizzata la finestra di dialogo Gestione Riferimenti. In questa finestra di dialogo è possibile aggiungere riferimenti ad altri progetti, assembly e DLL COM necessari per i progetti.

  7. Nella finestra di dialogo Gestione riferimenti, selezionare la casella di controllo per il progetto CalculatorLibrary e quindi selezionare OK.

    Screenshot della finestra di dialogo Gestione riferimenti.

    Il riferimento al progetto viene visualizzato in un nodo Progetti in Esplora soluzioni .

    screenshot di Esplora soluzioni con informazioni di riferimento sul progetto.

  8. In Program.csselezionare la classe Calculator e tutto il codice e premere CTRL+X per tagliarla. Quindi, in CalculatorLibrary.cs, incollare il codice nello spazio dei nomi CalculatorLibrary.

    Aggiungere anche public prima della classe Calculator per renderla visibile fuori dalla libreria.

    CalculatorLibrary.cs dovrebbe ora essere simile al codice seguente:

    // CalculatorLibrary.cs
    using System;
    
     namespace CalculatorLibrary
     {
         public class Calculator
         {
             public static double DoOperation(double num1, double num2, string op)
             {
                 double result = double.NaN; // Default value is "not-a-number" if an operation, such as division, could result in an error.
    
                 // Use a switch statement to do the math.
                 switch (op)
                 {
                     case "a":
                         result = num1 + num2;
                         break;
                     case "s":
                         result = num1 - num2;
                         break;
                     case "m":
                         result = num1 * num2;
                         break;
                     case "d":
                         // Ask the user to enter a non-zero divisor.
                         if (num2 != 0)
                         {
                             result = num1 / num2;
                         }
                         break;
                     // Return text for an incorrect option entry.
                     default:
                         break;
                 }
                 return result;
             }
         }
     }
    
  9. Program.cs ha anche un riferimento, ma un errore indica che la chiamata Calculator.DoOperation non viene risolta. L'errore è dovuto al fatto che CalculatorLibrary si trova in uno spazio dei nomi diverso. Per un riferimento completo, è possibile aggiungere lo spazio dei nomi CalculatorLibrary alla chiamata Calculator.DoOperation nel file Program.cs:

    // Program.cs
    result = CalculatorLibrary.Calculator.DoOperation(cleanNum1, cleanNum2, op);
    

    In alternativa, è possibile provare ad aggiungere una direttiva using all'inizio del file Program.cs:

    // Program.cs
    using CalculatorLibrary;
    

    L'aggiunta della direttiva using dovrebbe consentire di rimuovere lo spazio dei nomi CalculatorLibrary dal sito di chiamata, ma ora esiste un'ambiguità. È Calculator la classe in CalculatorLibraryo è Calculator il namespace?

    Per risolvere l'ambiguità, rinominare lo spazio dei nomi da Calculator in CalculatorProgram in Program.cs.

    // Program.cs
    namespace CalculatorProgram
    
  1. In Esplora soluzioni fare clic con il pulsante destro del mouse sul nodo della soluzione e scegliere Aggiungi>Nuovo progetto.

  2. Nella finestra Aggiungi un nuovo progetto, digitare libreria di classi nella casella di ricerca. Scegliere il modello di progetto della libreria di classi C#, e quindi selezionare Avanti.

    Screenshot della selezione del modello di progetto di libreria di classi.

  3. Nella schermata Configura il nuovo progetto digitare il nome del progetto CalculatorLibrarye quindi selezionare Avanti.

  4. Nella schermata Informazioni aggiuntive è selezionato .NET 8.0. Selezionare Crea.

    Visual Studio crea il nuovo progetto e lo aggiunge alla soluzione.

    screenshot di Esplora Soluzioni con il progetto della libreria di classi CalculatorLibrary aggiunto.

  5. Rinominare il file Class1.cs in CalculatorLibrary.cs. Per rinominare il file, è possibile fare clic con il pulsante destro del mouse sul nome in Esplora soluzioni e scegliere Rinomina, selezionare il nome e premere F2oppure selezionare di nuovo il nome e selezionare di nuovo per digitare.

    Un messaggio potrebbe chiedere se si desidera rinominare tutti i riferimenti a Class1 nel file. Non importa come rispondere, perché il codice verrà sostituito in un passaggio futuro.

  6. Aggiungere ora un riferimento al progetto, in modo che il primo progetto possa usare le API esposte dalla nuova libreria di classi. Fare clic con il pulsante destro del mouse sul nodo Dipendenze nel progetto Calcolatrice e scegliere Aggiungi riferimento al progetto.

    Screenshot della voce di menu

    Appare la finestra di dialogo Gestore Riferimenti. In questa finestra di dialogo è possibile aggiungere riferimenti ad altri progetti, assembly e DLL COM necessari per i progetti.

  7. Nella finestra di dialogo Gestione riferimenti, selezionare la casella di controllo per il progetto CalculatorLibrary e quindi selezionare OK.

    Screenshot della finestra di dialogo Gestione riferimenti.

    Il riferimento al progetto compare sotto un nodo Progetti in Esplora Soluzioni .

    screenshot di Esplora soluzioni con informazioni di riferimento sul progetto.

  8. In Program.csselezionare la classe Calculator e tutto il codice e premere CTRL+X per tagliarla. Quindi, incollare il codice nello spazio dei nomi CalculatorLibrary in CalculatorLibrary.cs.

    Aggiungere anche public prima della definizione della classe Calculator per esporla all'esterno della libreria.

    CalculatorLibrary.cs dovrebbe ora essere simile al codice seguente:

     // CalculatorLibrary.cs
     namespace CalculatorLibrary
     {
         public class Calculator
         {
             public static double DoOperation(double num1, double num2, string op)
             {
                 double result = double.NaN; // Default value is "not-a-number" if an operation, such as division, could result in an error.
    
                 // Use a switch statement to do the math.
                 switch (op)
                 {
                     case "a":
                         result = num1 + num2;
                         break;
                     case "s":
                         result = num1 - num2;
                         break;
                     case "m":
                         result = num1 * num2;
                         break;
                     case "d":
                         // Ask the user to enter a non-zero divisor.
                         if (num2 != 0)
                         {
                             result = num1 / num2;
                         }
                         break;
                     // Return text for an incorrect option entry.
                     default:
                         break;
                 }
                 return result;
             }
         }
     }
    
  9. Program.cs ha anche un riferimento, ma un errore indica che la chiamata Calculator.DoOperation non viene risolta. L'errore è dovuto al fatto che CalculatorLibrary si trova in uno spazio dei nomi diverso. Per un riferimento completamente qualificato, è possibile aggiungere lo spazio dei nomi CalculatorLibrary alla chiamata Calculator.DoOperation in Program.cs:

    // Program.cs
    result = CalculatorLibrary.Calculator.DoOperation(cleanNum1, cleanNum2, op);
    

    In alternativa, è possibile provare ad aggiungere una direttiva using all'inizio del file Program.cs:

    // Program.cs
    using CalculatorLibrary;
    

    L'aggiunta della direttiva using dovrebbe consentire di rimuovere lo spazio dei nomi CalculatorLibrary dal sito di chiamata.

    Se il codice Program.cs si trova nello spazio dei nomi Calculator, rinominare lo spazio dei nomi da Calculator a CalculatorProgram per rimuovere ambiguità tra nome della classe e nome dello spazio dei nomi.

Fare riferimento alle librerie .NET: Scrivere in un log

È possibile usare la classe traccia .NET per aggiungere un log di tutte le operazioni e scriverla in un file di testo. La classe Trace è utile anche per le tecniche di debug di stampa di base. La classe Trace si trova in System.Diagnosticse usa classi di System.IO come StreamWriter.

  1. Inizia aggiungendo le direttive using all'inizio di CalculatorLibrary.cs:

    // CalculatorLibrary.cs
    using System.IO;
    using System.Diagnostics;
    
  2. Questo utilizzo della classe Trace deve contenere un riferimento per la classe associata a un filestream. Questo requisito indica che il calcolatore funziona meglio come oggetto, quindi aggiungere un costruttore all'inizio della classe Calculator in CalculatorLibrary.cs.

    Rimuovere anche la parola chiave static per modificare il metodo DoOperation statico in un metodo membro.

    // CalculatorLibrary.cs
    public Calculator()
       {
           StreamWriter logFile = File.CreateText("calculator.log");
           Trace.Listeners.Add(new TextWriterTraceListener(logFile));
           Trace.AutoFlush = true;
           Trace.WriteLine("Starting Calculator Log");
           Trace.WriteLine(String.Format("Started {0}", System.DateTime.Now.ToString()));
       }
    
    public double DoOperation(double num1, double num2, string op)
       {
    
  3. Aggiungere l'output del log a ogni calcolo. DoOperation dovrebbe ora essere simile al codice seguente:

    // CalculatorLibrary.cs
    public double DoOperation(double num1, double num2, string op)
    {
         double result = double.NaN; // Default value is "not-a-number" if an operation, such as division, could result in an error.
    
         // Use a switch statement to do the math.
         switch (op)
         {
             case "a":
                 result = num1 + num2;
                 Trace.WriteLine(String.Format("{0} + {1} = {2}", num1, num2, result));
                 break;
             case "s":
                 result = num1 - num2;
                 Trace.WriteLine(String.Format("{0} - {1} = {2}", num1, num2, result));
                 break;
             case "m":
                 result = num1 * num2;
                 Trace.WriteLine(String.Format("{0} * {1} = {2}", num1, num2, result));
                 break;
             case "d":
                 // Ask the user to enter a non-zero divisor.
                 if (num2 != 0)
                 {
                     result = num1 / num2;
                     Trace.WriteLine(String.Format("{0} / {1} = {2}", num1, num2, result));
                 }
                     break;
             // Return text for an incorrect option entry.
             default:
                 break;
         }
         return result;
     }
    
  4. Di ritorno a Program.csuna sottolineatura ondulata rossa ora contrassegna la chiamata statica. Per correggere l'errore, creare una variabile calculator aggiungendo la riga di codice seguente subito prima del ciclo while (!endApp):

    // Program.cs
    Calculator calculator = new Calculator();
    

    Modificare anche il sito di chiamata DoOperation per fare riferimento all'oggetto denominato calculator in lettere minuscole. Il codice è ora una chiamata membro, anziché una chiamata a un metodo statico.

    // Program.cs
    result = calculator.DoOperation(cleanNum1, cleanNum2, op);
    
  5. Eseguire di nuovo l'app. Quando hai finito, fare clic con il pulsante destro del mouse sul nodo di progetto calcolatrice e scegliere Apri cartella in Esplora file.

  6. In Esplora File, navigare alla cartella di output in bin/Debug/net8.0 (o qualsiasi versione di .NET in uso) e aprire il file calculator.log. L'output dovrebbe essere simile al seguente:

    Starting Calculator Log
    Started 7/9/2020 1:58:19 PM
    1 + 2 = 3
    3 * 3 = 9
    

A questo punto, CalculatorLibrary.cs dovrebbe essere simile al codice seguente:

// CalculatorLibrary.cs
using System;
using System.IO;
using System.Diagnostics;

namespace CalculatorLibrary
{
    public class Calculator
    {

        public Calculator()
        {
            StreamWriter logFile = File.CreateText("calculator.log");
            Trace.Listeners.Add(new TextWriterTraceListener(logFile));
            Trace.AutoFlush = true;
            Trace.WriteLine("Starting Calculator Log");
            Trace.WriteLine(String.Format("Started {0}", System.DateTime.Now.ToString()));
        }

        public double DoOperation(double num1, double num2, string op)
        {
            double result = double.NaN; // Default value is "not-a-number" if an operation, such as division, could result in an error.

            // Use a switch statement to do the math.
            switch (op)
            {
                case "a":
                    result = num1 + num2;
                    Trace.WriteLine(String.Format("{0} + {1} = {2}", num1, num2, result));
                    break;
                case "s":
                    result = num1 - num2;
                    Trace.WriteLine(String.Format("{0} - {1} = {2}", num1, num2, result));
                    break;
                case "m":
                    result = num1 * num2;
                    Trace.WriteLine(String.Format("{0} * {1} = {2}", num1, num2, result));
                    break;
                case "d":
                    // Ask the user to enter a non-zero divisor.
                    if (num2 != 0)
                    {
                        result = num1 / num2;
                        Trace.WriteLine(String.Format("{0} / {1} = {2}", num1, num2, result));
                    }
                    break;
                // Return text for an incorrect option entry.
                default:
                    break;
            }
            return result;
        }
    }
}

Program.cs dovrebbe essere simile al codice seguente:

// Program.cs
using System;
using CalculatorLibrary;

namespace CalculatorProgram
{

    class Program
    {
        static void Main(string[] args)
        {
            bool endApp = false;
            // Display title as the C# console calculator app.
            Console.WriteLine("Console Calculator in C#\r");
            Console.WriteLine("------------------------\n");

            Calculator calculator = new Calculator();
            while (!endApp)
            {
                // Declare variables and set to empty.
                string numInput1 = "";
                string numInput2 = "";
                double result = 0;

                // Ask the user to type the first number.
                Console.Write("Type a number, and then press Enter: ");
                numInput1 = Console.ReadLine();

                double cleanNum1 = 0;
                while (!double.TryParse(numInput1, out cleanNum1))
                {
                    Console.Write("This is not valid input. Please enter an integer value: ");
                    numInput1 = Console.ReadLine();
                }

                // Ask the user to type the second number.
                Console.Write("Type another number, and then press Enter: ");
                numInput2 = Console.ReadLine();

                double cleanNum2 = 0;
                while (!double.TryParse(numInput2, out cleanNum2))
                {
                    Console.Write("This is not valid input. Please enter an integer value: ");
                    numInput2 = Console.ReadLine();
                }

                // Ask the user to choose an operator.
                Console.WriteLine("Choose an operator from the following list:");
                Console.WriteLine("\ta - Add");
                Console.WriteLine("\ts - Subtract");
                Console.WriteLine("\tm - Multiply");
                Console.WriteLine("\td - Divide");
                Console.Write("Your option? ");

                string op = Console.ReadLine();

                try
                {
                    result = calculator.DoOperation(cleanNum1, cleanNum2, op); 
                    if (double.IsNaN(result))
                    {
                        Console.WriteLine("This operation will result in a mathematical error.\n");
                    }
                    else Console.WriteLine("Your result: {0:0.##}\n", result);
                }
                catch (Exception e)
                {
                    Console.WriteLine("Oh no! An exception occurred trying to do the math.\n - Details: " + e.Message);
                }

                Console.WriteLine("------------------------\n");

                // Wait for the user to respond before closing.
                Console.Write("Press 'n' and Enter to close the app, or press any other key and Enter to continue: ");
                if (Console.ReadLine() == "n") endApp = true;

                Console.WriteLine("\n"); // Friendly linespacing.
            }
            return;
        }
    }
}

È possibile usare la classe traccia .NET per aggiungere un log di tutte le operazioni e scriverla in un file di testo. La classe Trace è utile anche per le tecniche di debug di stampa di base. La classe Trace si trova in System.Diagnosticse usa classi di System.IO come StreamWriter.

  1. Per iniziare, aggiungere le direttive using in cima a CalculatorLibrary.cs:

    // CalculatorLibrary.cs
    using System.Diagnostics;
    
  2. Questo utilizzo della classe Trace deve contenere un riferimento per la classe associata a un filestream. Questo requisito indica che il calcolatore funziona meglio come oggetto, quindi aggiungere un costruttore all'inizio della classe Calculator in CalculatorLibrary.cs.

    Rimuovere anche la parola chiave static per modificare il metodo DoOperation statico in un metodo membro.

    // CalculatorLibrary.cs
    public Calculator()
       {
           StreamWriter logFile = File.CreateText("calculator.log");
           Trace.Listeners.Add(new TextWriterTraceListener(logFile));
           Trace.AutoFlush = true;
           Trace.WriteLine("Starting Calculator Log");
           Trace.WriteLine(String.Format("Started {0}", System.DateTime.Now.ToString()));
       }
    
    public double DoOperation(double num1, double num2, string op)
       {
    
  3. Aggiungere l'output del log a ogni calcolo. DoOperation dovrebbe ora essere simile al codice seguente:

    // CalculatorLibrary.cs
    public double DoOperation(double num1, double num2, string op)
    {
         double result = double.NaN; // Default value is "not-a-number" if an operation, such as division, could result in an error.
    
         // Use a switch statement to do the math.
         switch (op)
         {
             case "a":
                 result = num1 + num2;
                 Trace.WriteLine(String.Format("{0} + {1} = {2}", num1, num2, result));
                 break;
             case "s":
                 result = num1 - num2;
                 Trace.WriteLine(String.Format("{0} - {1} = {2}", num1, num2, result));
                 break;
             case "m":
                 result = num1 * num2;
                 Trace.WriteLine(String.Format("{0} * {1} = {2}", num1, num2, result));
                 break;
             case "d":
                 // Ask the user to enter a non-zero divisor.
                 if (num2 != 0)
                 {
                     result = num1 / num2;
                     Trace.WriteLine(String.Format("{0} / {1} = {2}", num1, num2, result));
                 }
                     break;
             // Return text for an incorrect option entry.
             default:
                 break;
         }
         return result;
     }
    
  4. Tornando su Program.cs, ora una sottolineatura ondulata rossa contrassegna la chiamata statica. Per correggere l'errore, creare una variabile calculator aggiungendo la riga di codice seguente subito prima del ciclo while (!endApp):

    // Program.cs
    Calculator calculator = new Calculator();
    

    Modificare anche il sito di chiamata DoOperation per fare riferimento all'oggetto denominato calculator in lettere minuscole. Il codice è ora una chiamata membro, anziché una chiamata a un metodo statico.

    // Program.cs
    result = calculator.DoOperation(cleanNum1, cleanNum2, op);
    
  5. Eseguire di nuovo l'app. Al termine, fare clic con il pulsante destro del mouse sul nodo del progetto Calcolatrice e scegliere Apri cartella in Esplora File.

  6. In Esplora file passare alla cartella di output in bin/Debug/e aprire il file calculator.log. L'output dovrebbe essere simile al seguente:

    Starting Calculator Log
    Started 7/9/2020 1:58:19 PM
    1 + 2 = 3
    3 * 3 = 9
    

A questo punto, CalculatorLibrary.cs dovrebbe essere simile al codice seguente:

// CalculatorLibrary.cs
using System.Diagnostics;

namespace CalculatorLibrary
{
    public class Calculator
    {

        public Calculator()
        {
            StreamWriter logFile = File.CreateText("calculator.log");
            Trace.Listeners.Add(new TextWriterTraceListener(logFile));
            Trace.AutoFlush = true;
            Trace.WriteLine("Starting Calculator Log");
            Trace.WriteLine(String.Format("Started {0}", System.DateTime.Now.ToString()));
        }

        public double DoOperation(double num1, double num2, string op)
        {
            double result = double.NaN; // Default value is "not-a-number" if an operation, such as division, could result in an error.

            // Use a switch statement to do the math.
            switch (op)
            {
                case "a":
                    result = num1 + num2;
                    Trace.WriteLine(String.Format("{0} + {1} = {2}", num1, num2, result));
                    break;
                case "s":
                    result = num1 - num2;
                    Trace.WriteLine(String.Format("{0} - {1} = {2}", num1, num2, result));
                    break;
                case "m":
                    result = num1 * num2;
                    Trace.WriteLine(String.Format("{0} * {1} = {2}", num1, num2, result));
                    break;
                case "d":
                    // Ask the user to enter a non-zero divisor.
                    if (num2 != 0)
                    {
                        result = num1 / num2;
                        Trace.WriteLine(String.Format("{0} / {1} = {2}", num1, num2, result));
                    }
                    break;
                // Return text for an incorrect option entry.
                default:
                    break;
            }
            return result;
        }
    }
}

Program.cs dovrebbe essere simile al codice seguente:

// Program.cs
using CalculatorLibrary;

namespace CalculatorProgram
{

    class Program
    {
        static void Main(string[] args)
        {
            bool endApp = false;
            // Display title as the C# console calculator app.
            Console.WriteLine("Console Calculator in C#\r");
            Console.WriteLine("------------------------\n");

            Calculator calculator = new Calculator();
            while (!endApp)
            {
                // Declare variables and set to empty.
                // Use Nullable types (with ?) to match type of System.Console.ReadLine
                string? numInput1 = "";
                string? numInput2 = "";
                double result = 0;

                // Ask the user to type the first number.
                Console.Write("Type a number, and then press Enter: ");
                numInput1 = Console.ReadLine();

                double cleanNum1 = 0;
                while (!double.TryParse(numInput1, out cleanNum1))
                {
                    Console.Write("This is not valid input. Please enter an integer value: ");
                    numInput1 = Console.ReadLine();
                }

                // Ask the user to type the second number.
                Console.Write("Type another number, and then press Enter: ");
                numInput2 = Console.ReadLine();

                double cleanNum2 = 0;
                while (!double.TryParse(numInput2, out cleanNum2))
                {
                    Console.Write("This is not valid input. Please enter an integer value: ");
                    numInput2 = Console.ReadLine();
                }

                // Ask the user to choose an operator.
                Console.WriteLine("Choose an operator from the following list:");
                Console.WriteLine("\ta - Add");
                Console.WriteLine("\ts - Subtract");
                Console.WriteLine("\tm - Multiply");
                Console.WriteLine("\td - Divide");
                Console.Write("Your option? ");

                string? op = Console.ReadLine();

                // Validate input is not null, and matches the pattern
                if (op == null || ! Regex.IsMatch(op, "[a|s|m|d]"))
                {
                   Console.WriteLine("Error: Unrecognized input.");
                }
                else
                { 
                   try
                   {
                       result = calculator.DoOperation(cleanNum1, cleanNum2, op); 
                       if (double.IsNaN(result))
                       {
                           Console.WriteLine("This operation will result in a mathematical error.\n");
                       }
                       else Console.WriteLine("Your result: {0:0.##}\n", result);
                   }
                   catch (Exception e)
                   {
                       Console.WriteLine("Oh no! An exception occurred trying to do the math.\n - Details: " + e.Message);
                   }
                }
                Console.WriteLine("------------------------\n");

                // Wait for the user to respond before closing.
                Console.Write("Press 'n' and Enter to close the app, or press any other key and Enter to continue: ");
                if (Console.ReadLine() == "n") endApp = true;

                Console.WriteLine("\n"); // Friendly linespacing.
            }
            return;
        }
    }
}

Aggiungere un pacchetto NuGet: scrivere in un file JSON

Per eseguire operazioni di output in JSON, un formato diffuso e portabile per l'archiviazione dei dati degli oggetti, è possibile fare riferimento al pacchetto NuGet Newtonsoft. Json. I pacchetti NuGet sono il metodo di distribuzione principale per le librerie di classi .NET.

  1. In Esplora soluzioni , fare clic con il pulsante destro del mouse sul nodo Dipendenze per il progetto CalculatorLibrary e scegliere Gestisci Pacchetti NuGet.

    Screenshot di Gestisci pacchetti NuGet nel menu di scelta rapida.

    Screenshot di Gestisci pacchetti NuGet nel menu di scelta rapida.

    Si apre il Gestore pacchetti NuGet.

    screenshot della Gestione pacchetti NuGet.

  2. Cercare e selezionare il pacchetto Newtonsoft.Json, e selezionare Installa.

    screenshot delle informazioni sul pacchetto NuGet Newtonsoft J SON in Gestione pacchetti NuGet.

    Visual Studio scarica il pacchetto e lo aggiunge al progetto. Viene visualizzata una nuova voce nel nodo Riferimenti in Esplora soluzioni .

    screenshot delle informazioni sul pacchetto NuGet Newtonsoft J SON in Gestione pacchetti NuGet.

    Se viene richiesto se accettare le modifiche, selezionare OK.

    Visual Studio scarica il pacchetto e lo aggiunge al progetto. Viene visualizzata una nuova voce nel nodo Pacchetti in Esplora soluzioni.

    Aggiungere una direttiva using per Newtonsoft.Json all'inizio di CalculatorLibrary.cs.

    // CalculatorLibrary.cs
    using Newtonsoft.Json;
    
  3. Creare l'oggetto membro JsonWriter e sostituire il costruttore Calculator con il codice seguente:

         // CalculatorLibrary.cs
         JsonWriter writer;
    
         public Calculator()
         {
             StreamWriter logFile = File.CreateText("calculatorlog.json");
             logFile.AutoFlush = true;
             writer = new JsonTextWriter(logFile);
             writer.Formatting = Formatting.Indented;
             writer.WriteStartObject();
             writer.WritePropertyName("Operations");
             writer.WriteStartArray();
         }
    
  4. Modificare il metodo DoOperation per aggiungere il codice json writer:

         // CalculatorLibrary.cs
         public double DoOperation(double num1, double num2, string op)
         {
             double result = double.NaN; // Default value is "not-a-number" if an operation, such as division, could result in an error.
             writer.WriteStartObject();
             writer.WritePropertyName("Operand1");
             writer.WriteValue(num1);
             writer.WritePropertyName("Operand2");
             writer.WriteValue(num2);
             writer.WritePropertyName("Operation");
             // Use a switch statement to do the math.
             switch (op)
             {
                 case "a":
                     result = num1 + num2;
                     writer.WriteValue("Add");
                     break;
                 case "s":
                     result = num1 - num2;
                     writer.WriteValue("Subtract");
                     break;
                 case "m":
                     result = num1 * num2;
                     writer.WriteValue("Multiply");
                     break;
                 case "d":
                     // Ask the user to enter a non-zero divisor.
                     if (num2 != 0)
                     {
                         result = num1 / num2;
                     }
                     writer.WriteValue("Divide");
                     break;
                 // Return text for an incorrect option entry.
                 default:
                     break;
             }
             writer.WritePropertyName("Result");
             writer.WriteValue(result);
             writer.WriteEndObject();
    
             return result;
         }
    
  5. Aggiungere un metodo per completare la sintassi JSON al termine dell'immissione dei dati dell'operazione da parte dell'utente.

     // CalculatorLibrary.cs
     public void Finish()
     {
         writer.WriteEndArray();
         writer.WriteEndObject();
         writer.Close();
     }
    
  6. Alla fine di Program.cs, prima del return;, aggiungere una chiamata a Finish:

         // Program.cs
             // Add call to close the JSON writer before return
             calculator.Finish();
             return;
         }
    
  7. Compilare ed eseguire l'app e dopo aver completato alcune operazioni, chiudere l'app immettendo il comando n.

  8. Aprire il file calculatorlog.json in Esplora file. Verrà visualizzato un contenuto simile al seguente:

    {
     "Operations": [
         {
         "Operand1": 2.0,
         "Operand2": 3.0,
         "Operation": "Add",
         "Result": 5.0
         },
         {
         "Operand1": 3.0,
         "Operand2": 4.0,
         "Operation": "Multiply",
         "Result": 12.0
         }
     ]
    }
    

Debug: impostare e raggiungere un punto di interruzione

Il debugger di Visual Studio è uno strumento potente. Il debugger può eseguire il codice per trovare il punto esatto in cui si verifica un errore di programmazione. È quindi possibile comprendere quali correzioni è necessario apportare e apportare modifiche temporanee in modo da poter continuare a eseguire l'app.

  1. In Program.cs, fare clic nel margine a sinistra della riga di codice seguente. È anche possibile fare clic nella riga e selezionare F9oppure fare clic con il pulsante destro del mouse sulla riga e selezionare punto di interruzione>Inserisci punto di interruzione.

    // Program.cs
    result = calculator.DoOperation(cleanNum1, cleanNum2, op);
    

    Il punto rosso visualizzato indica un punto di interruzione. Puoi usare i punti di interruzione per sospendere l'app ed esaminare il codice. È possibile impostare un punto di interruzione in qualsiasi riga di codice eseguibile.

    Screenshot che mostra l'impostazione di un punto di interruzione.

  2. Compilare ed eseguire l'app. Immettere i valori seguenti per il calcolo:

    • Per il primo numero immettere 8.
    • Per il secondo numero immettere 0.
    • Per l'operatore, divertiamoci un po'. Immettere d.

    L'app sospende dove è stato creato il punto di interruzione, indicato dal puntatore giallo a sinistra e dal codice evidenziato. Il codice evidenziato non è ancora stato eseguito.

    Screenshot del raggiungimento di un punto di interruzione

    Ora, con l'app sospesa, è possibile controllare lo stato dell'applicazione.

Debug: Visualizza le variabili

  1. Nel codice evidenziato passare il puntatore del mouse sulle variabili, ad esempio cleanNum1 e op. I valori correnti per queste variabili, rispettivamente 8 e d, vengono visualizzati in Suggerimenti dati.

    Screenshot che mostra la visualizzazione di un DataTip.

    Durante il debug, verificare se le variabili contengono i valori previsti è spesso fondamentale per risolvere i problemi.

  2. Nel riquadro inferiore, guarda la finestra variabili locali. Se è chiuso, selezionare Debug>Windows>Locals per aprirlo.

    La finestra variabili locali mostra ogni variabile attualmente nell'ambito, insieme al relativo valore e tipo.

    Screenshot della finestra Variabili locali.

    Screenshot della finestra Variabili locali.

  3. Guardare la finestra Auto.

    La finestra Auto è simile alla finestra variabili locali, ma mostra le variabili immediatamente precedenti e dopo la riga di codice corrente in cui l'app è sospesa.

    Nota

    Se non viene visualizzata la finestra Auto, selezionare Debug>Windows>Auto per aprirla.

Eseguire quindi il codice nel debugger un'istruzione alla volta, denominata istruzione.

Debug: Eseguire passo passo il codice

  1. Premere F11oppure selezionare Debug>Esegui istruzione.

    Utilizzando il comando Passa all'interno, l'app esegue l'istruzione corrente e passa all'istruzione eseguibile successiva, solitamente la riga di codice successiva. Il puntatore giallo a sinistra indica sempre l'istruzione corrente.

    Screenshot del comando di avanzamento

    È sufficiente passare al metodo DoOperation nella classe Calculator.

  2. Per ottenere una visione gerarchica del flusso del programma, consulta la finestra Call Stack. Se è chiuso, selezionare Debug>Stack di chiamate di Windows> per aprirlo.

    Screenshot dello stack di chiamate

    Questa visualizzazione mostra il metodo Calculator.DoOperation corrente, indicato dal puntatore giallo. La seconda riga mostra la funzione che ha chiamato il metodo , dal metodo Main in Program.cs.

    La finestra stack di chiamate mostra l'ordine in cui vengono chiamati i metodi e le funzioni. Questa finestra consente anche l'accesso a molte funzionalità del debugger, ad esempio Vai al codice sorgente, dal relativo menu di scelta rapida.

  3. Premere F10oppure selezionare Debug>Passa Sopra, più volte fino a quando l'app viene sospesa sull'istruzione switch.

    // CalculatorLibrary.cs
    switch (op)
    {
    

    Il comando Step Over è simile al comando Step Into, ad eccezione del fatto che se l'istruzione corrente chiama una funzione, il debugger esegue il codice nella funzione e non sospende l'esecuzione fino a quando la funzione non viene restituita. Step Over è più veloce di Step Into se non si è interessati a una funzione particolare.

  4. Premere F10 ancora una volta, in modo che l'app venga sospesa nella riga di codice seguente.

    // CalculatorLibrary.cs
    if (num2 != 0)
    {
    

    Questo codice verifica la presenza di un caso di divisione per zero. Se l'app continua, genera un'eccezione generale (un errore), ma potrebbe essere necessario provare qualcos'altro, ad esempio visualizzare il valore restituito effettivo nella console. Un'opzione consiste nell'usare una funzionalità del debugger denominata di modifica e continuazione per apportare modifiche al codice e quindi continuare il debug. Tuttavia, esiste un altro trucco per modificare temporaneamente il flusso di esecuzione.

Debug: Testare una modifica temporanea

  1. Selezionare il puntatore giallo, attualmente sospeso nell'istruzione if (num2 != 0) e trascinarlo nell'istruzione seguente:

    // CalculatorLibrary.cs
    result = num1 / num2;
    

    Se si trascina il puntatore, l'app ignora completamente l'istruzione if, quindi è possibile vedere cosa accade quando si divide per zero.

  2. Premere F10 per eseguire la riga di codice.

  3. Se si passa il puntatore del mouse sulla variabile result, viene visualizzato il valore Infinity. In C#, Infinity è il risultato quando si divide per zero.

  4. Premere F5oppure selezionare Debug>Continua il debug.

    Il simbolo infinito viene visualizzato nella console come risultato dell'operazione matematica.

  5. Chiudere correttamente l'app immettendo il comando n.

Codice completato

Ecco il codice completo per il file CalculatorLibrary.cs, dopo aver completato tutti i passaggi:

// CalculatorLibrary.cs
using System;
using System.IO;
using Newtonsoft.Json;

namespace CalculatorLibrary
{
    public class Calculator
    {

        JsonWriter writer;

        public Calculator()
        {
            StreamWriter logFile = File.CreateText("calculatorlog.json");
            logFile.AutoFlush = true;
            writer = new JsonTextWriter(logFile);
            writer.Formatting = Formatting.Indented;
            writer.WriteStartObject();
            writer.WritePropertyName("Operations");
            writer.WriteStartArray();
        }

        public double DoOperation(double num1, double num2, string op)
        {
            double result = double.NaN; // Default value is "not-a-number" if an operation, such as division, could result in an error.
            writer.WriteStartObject();
            writer.WritePropertyName("Operand1");
            writer.WriteValue(num1);
            writer.WritePropertyName("Operand2");
            writer.WriteValue(num2);
            writer.WritePropertyName("Operation");
            // Use a switch statement to do the math.
            switch (op)
            {
                case "a":
                    result = num1 + num2;
                    writer.WriteValue("Add");
                    break;
                case "s":
                    result = num1 - num2;
                    writer.WriteValue("Subtract");
                    break;
                case "m":
                    result = num1 * num2;
                    writer.WriteValue("Multiply");
                    break;
                case "d":
                    // Ask the user to enter a non-zero divisor.
                    if (num2 != 0)
                    {
                        result = num1 / num2;
                    }
                    writer.WriteValue("Divide");
                    break;
                // Return text for an incorrect option entry.
                default:
                    break;
            }
            writer.WritePropertyName("Result");
            writer.WriteValue(result);
            writer.WriteEndObject();

            return result;
        }

        public void Finish()
        {
            writer.WriteEndArray();
            writer.WriteEndObject();
            writer.Close();
        }
    }
}

Ecco il codice per Program.cs:

// Program.cs
using System;
using CalculatorLibrary;

namespace CalculatorProgram
{

    class Program
    {
        static void Main(string[] args)
        {
            bool endApp = false;
            // Display title as the C# console calculator app.
            Console.WriteLine("Console Calculator in C#\r");
            Console.WriteLine("------------------------\n");

            Calculator calculator = new Calculator();
            while (!endApp)
            {
                // Declare variables and set to empty.
                string numInput1 = "";
                string numInput2 = "";
                double result = 0;

                // Ask the user to type the first number.
                Console.Write("Type a number, and then press Enter: ");
                numInput1 = Console.ReadLine();

                double cleanNum1 = 0;
                while (!double.TryParse(numInput1, out cleanNum1))
                {
                    Console.Write("This is not valid input. Please enter an integer value: ");
                    numInput1 = Console.ReadLine();
                }

                // Ask the user to type the second number.
                Console.Write("Type another number, and then press Enter: ");
                numInput2 = Console.ReadLine();

                double cleanNum2 = 0;
                while (!double.TryParse(numInput2, out cleanNum2))
                {
                    Console.Write("This is not valid input. Please enter an integer value: ");
                    numInput2 = Console.ReadLine();
                }

                // Ask the user to choose an operator.
                Console.WriteLine("Choose an operator from the following list:");
                Console.WriteLine("\ta - Add");
                Console.WriteLine("\ts - Subtract");
                Console.WriteLine("\tm - Multiply");
                Console.WriteLine("\td - Divide");
                Console.Write("Your option? ");

                string op = Console.ReadLine();

                try
                {
                    result = calculator.DoOperation(cleanNum1, cleanNum2, op); 
                    if (double.IsNaN(result))
                    {
                        Console.WriteLine("This operation will result in a mathematical error.\n");
                    }
                    else Console.WriteLine("Your result: {0:0.##}\n", result);
                }
                catch (Exception e)
                {
                    Console.WriteLine("Oh no! An exception occurred trying to do the math.\n - Details: " + e.Message);
                }

                Console.WriteLine("------------------------\n");

                // Wait for the user to respond before closing.
                Console.Write("Press 'n' and Enter to close the app, or press any other key and Enter to continue: ");
                if (Console.ReadLine() == "n") endApp = true;

                Console.WriteLine("\n"); // Friendly linespacing.
            }
            calculator.Finish();
            return;
        }
    }
}

Ecco il codice completo per il file CalculatorLibrary.cs, dopo aver completato tutti i passaggi:

// CalculatorLibrary.cs
using Newtonsoft.Json;

namespace CalculatorLibrary
{
    public class Calculator
    {

        JsonWriter writer;

        public Calculator()
        {
            StreamWriter logFile = File.CreateText("calculatorlog.json");
            logFile.AutoFlush = true;
            writer = new JsonTextWriter(logFile);
            writer.Formatting = Formatting.Indented;
            writer.WriteStartObject();
            writer.WritePropertyName("Operations");
            writer.WriteStartArray();
        }

        public double DoOperation(double num1, double num2, string op)
        {
            double result = double.NaN; // Default value is "not-a-number" if an operation, such as division, could result in an error.
            writer.WriteStartObject();
            writer.WritePropertyName("Operand1");
            writer.WriteValue(num1);
            writer.WritePropertyName("Operand2");
            writer.WriteValue(num2);
            writer.WritePropertyName("Operation");
            // Use a switch statement to do the math.
            switch (op)
            {
                case "a":
                    result = num1 + num2;
                    writer.WriteValue("Add");
                    break;
                case "s":
                    result = num1 - num2;
                    writer.WriteValue("Subtract");
                    break;
                case "m":
                    result = num1 * num2;
                    writer.WriteValue("Multiply");
                    break;
                case "d":
                    // Ask the user to enter a non-zero divisor.
                    if (num2 != 0)
                    {
                        result = num1 / num2;
                    }
                    writer.WriteValue("Divide");
                    break;
                // Return text for an incorrect option entry.
                default:
                    break;
            }
            writer.WritePropertyName("Result");
            writer.WriteValue(result);
            writer.WriteEndObject();

            return result;
        }

        public void Finish()
        {
            writer.WriteEndArray();
            writer.WriteEndObject();
            writer.Close();
        }
    }
}

Ecco il codice per Program.cs:

// Program.cs
using CalculatorLibrary;

namespace CalculatorProgram
{

    class Program
    {
        static void Main(string[] args)
        {
            bool endApp = false;
            // Display title as the C# console calculator app.
            Console.WriteLine("Console Calculator in C#\r");
            Console.WriteLine("------------------------\n");

            Calculator calculator = new Calculator();
            while (!endApp)
            {
                // Declare variables and set to empty.
                // Use Nullable types (with ?) to match type of System.Console.ReadLine
                string? numInput1 = "";
                string? numInput2 = "";
                double result = 0;

                // Ask the user to type the first number.
                Console.Write("Type a number, and then press Enter: ");
                numInput1 = Console.ReadLine();

                double cleanNum1 = 0;
                while (!double.TryParse(numInput1, out cleanNum1))
                {
                    Console.Write("This is not valid input. Please enter an integer value: ");
                    numInput1 = Console.ReadLine();
                }

                // Ask the user to type the second number.
                Console.Write("Type another number, and then press Enter: ");
                numInput2 = Console.ReadLine();

                double cleanNum2 = 0;
                while (!double.TryParse(numInput2, out cleanNum2))
                {
                    Console.Write("This is not valid input. Please enter an integer value: ");
                    numInput2 = Console.ReadLine();
                }

                // Ask the user to choose an operator.
                Console.WriteLine("Choose an operator from the following list:");
                Console.WriteLine("\ta - Add");
                Console.WriteLine("\ts - Subtract");
                Console.WriteLine("\tm - Multiply");
                Console.WriteLine("\td - Divide");
                Console.Write("Your option? ");

                string? op = Console.ReadLine();

                // Validate input is not null, and matches the pattern
                if (op == null || ! Regex.IsMatch(op, "[a|s|m|d]"))
                {
                   Console.WriteLine("Error: Unrecognized input.");
                }
                else
                { 
                   try
                   {
                       result = calculator.DoOperation(cleanNum1, cleanNum2, op); 
                       if (double.IsNaN(result))
                       {
                           Console.WriteLine("This operation will result in a mathematical error.\n");
                       }
                       else Console.WriteLine("Your result: {0:0.##}\n", result);
                   }
                   catch (Exception e)
                   {
                       Console.WriteLine("Oh no! An exception occurred trying to do the math.\n - Details: " + e.Message);
                   }
                }
                Console.WriteLine("------------------------\n");

                // Wait for the user to respond before closing.
                Console.Write("Press 'n' and Enter to close the app, or press any other key and Enter to continue: ");
                if (Console.ReadLine() == "n") endApp = true;

                Console.WriteLine("\n"); // Friendly linespacing.
            }
            calculator.Finish();
            return;
        }
    }
}

Passaggi successivi

Congratulazioni per aver completato questa esercitazione. Per altre informazioni, continuare con il contenuto seguente: