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. Eseguire l'app console C# creata nella parte 1 di questa esercitazione ed esplorare 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 si completano le attività seguenti:

  • Aggiungere un secondo progetto.
  • Librerie di riferimento e aggiungere pacchetti.
  • Eseguire il debug del codice.
  • Esaminare 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 libreria di classi C# e quindi selezionare Avanti.

    Screenshot of Class Library project template selection.

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

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

    Screenshot of Solution Explorer with the CalculatorLibrary class library project added.

  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 F2 oppure selezionare di nuovo il nome e selezionare di nuovo per digitare.

    Un messaggio potrebbe chiedere se si desidera rinominare i riferimenti in 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 Calculator e scegliere Aggiungi riferimento progetto.

    Screenshot of the Add Project Reference menu item.

    Verrà 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 of the Reference Manager dialog box.

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

    Screenshot of Solution Explorer with project reference.

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

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

    CalculatorLibrary.cs dovrebbe ora essere simile al codice seguente:

    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 Calculator.DoOperation chiamata 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 CalculatorLibrary spazio dei nomi alla Calculator.DoOperation chiamata:

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

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

    using CalculatorLibrary;
    

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

    Per risolvere l'ambiguità, rinominare lo spazio dei nomi da Calculator a CalculatorProgram in 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 libreria di classi C# e quindi selezionare Avanti.

    Screenshot of Class Library project template selection.

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

  4. Nella schermata Informazioni aggiuntive è selezionata l'opzione .NET 8.0. Seleziona Crea.

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

    Screenshot of Solution Explorer with the CalculatorLibrary class library project added.

  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 F2 oppure selezionare di nuovo il nome e selezionare di nuovo per digitare.

    Un messaggio potrebbe chiedere se si desidera rinominare tutti i riferimenti in 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 Calculator e scegliere Aggiungi riferimento progetto.

    Screenshot of the Add Project Reference menu item.

    Verrà 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 of the Reference Manager dialog box.

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

    Screenshot of Solution Explorer with project reference.

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

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

    CalculatorLibrary.cs dovrebbe ora essere simile al codice seguente:

     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 Calculator.DoOperation chiamata 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 CalculatorLibrary spazio dei nomi alla Calculator.DoOperation chiamata:

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

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

    using CalculatorLibrary;
    

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

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

    namespace CalculatorProgram
    

Fare riferimento alle librerie .NET: Scrivere in un log

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

  1. Per iniziare, aggiungere le using direttive nella parte superiore di CalculatorLibrary.cs:

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

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

    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:

    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. Tornare a Program.cs, una sottolineatura ondulata rossa contrassegna ora la chiamata statica. Per correggere l'errore, creare una calculator variabile aggiungendo la riga di codice seguente subito prima del while (!endApp) ciclo:

    Calculator calculator = new Calculator();
    

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

    result = calculator.DoOperation(cleanNum1, cleanNum2, op);
    
  5. Eseguire nuovamente l'app. Al termine, fare clic con il pulsante destro del mouse sul nodo del progetto Calculator 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:

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:

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 Trace .NET per aggiungere un log di tutte le operazioni e scriverlo in un file di testo. La Trace classe è utile anche per le tecniche di debug di stampa di base. La Trace classe è in System.Diagnosticse usa System.IO classi come StreamWriter.

  1. Per iniziare, aggiungere le using direttive nella parte superiore di CalculatorLibrary.cs:

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

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

    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:

    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. Tornare a Program.cs, una sottolineatura ondulata rossa contrassegna ora la chiamata statica. Per correggere l'errore, creare una calculator variabile aggiungendo la riga di codice seguente subito prima del while (!endApp) ciclo:

    Calculator calculator = new Calculator();
    

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

    result = calculator.DoOperation(cleanNum1, cleanNum2, op);
    
  5. Eseguire nuovamente l'app. Al termine, fare clic con il pulsante destro del mouse sul nodo del progetto Calculator 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:

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:

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;
        }
    }
}

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 of Manage NuGet Packages on the shortcut menu.

    Screenshot of Manage NuGet Packages on the shortcut menu.

    Verrà aperto il Gestione pacchetti NuGet.

    Screenshot of the NuGet Package Manager.

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

    Screenshot of Newtonsoft J SON NuGet package information in the NuGet Package Manager.

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

    Screenshot of Newtonsoft J SON NuGet package information in the NuGet Package Manager. Se viene richiesto se accettare le modifiche, selezionare OK.

    Visual Studio scarica il pacchetto e lo aggiunge al progetto. Una nuova voce viene visualizzata in un nodo Pacchetti in Esplora soluzioni.

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

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

         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 DoOperation metodo per aggiungere il codice JSON writer :

         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.

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

             // Add call to close the JSON writer before return
             calculator.Finish();
             return;
         }
    
  7. Compilare ed eseguire l'app e dopo aver completato l'immissione di 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 sulla barra a sinistra della riga di codice seguente. È anche possibile fare clic sulla riga e scegliere F9 oppure fare clic con il pulsante destro del mouse sulla riga e scegliere Inserisci punto> di interruzione.

    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 that shows setting a breakpoint.

  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, diamo un po' di divertimento. 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 of hitting a breakpoint

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

Debug: Visualizzare le variabili

  1. Nel codice evidenziato passare il puntatore del mouse sulle variabili come cleanNum1 e op. I valori correnti per queste variabili 8 ed, rispettivamente, vengono visualizzati in Data Suggerimenti.

    Screenshot that shows viewing a DataTip.

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

  2. Nel riquadro inferiore esaminare la finestra Variabili locali . Se è chiuso, selezionare Debug>variabili locali di Windows>per aprirlo.

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

    Screenshot of the Locals window.

    Screenshot of the Locals window.

  3. Esaminare 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 viene sospesa l'app.

    Nota

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

Successivamente, eseguire il codice nel debugger un'istruzione alla volta, denominata istruzione.

Debug: Eseguire l'istruzione del codice

  1. Premere F11 o selezionare Debug>Passaggio in.

    Usando il comando Esegui istruzione istruzione, l'app esegue l'istruzione corrente e passa all'istruzione eseguibile successiva, in genere la riga di codice successiva. Il puntatore giallo a sinistra indica sempre l'istruzione corrente.

    Screenshot of step into command

    È stato appena inserito il DoOperation metodo nella Calculator classe .

  2. Per ottenere un'occhiata gerarchica al flusso del programma, esaminare la finestra Stack di chiamate. Se è chiuso, selezionare Debug>stack di chiamate di Windows>per aprirlo.

    Screenshot of the call stack

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

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

  3. Premere F10 o selezionare Debug>Passaggio su più volte fino a quando l'app non viene sospesa nell'istruzione.switch

    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 Esegui istruzione in se non si è interessati a una funzione specifica.

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

    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 edit-and-continue 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:

    result = num1 / num2;
    

    Il trascinamento del puntatore qui fa sì che l'app ignori completamente l'istruzione if , in modo da 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 result variabile, viene visualizzato il valore Infinity. In C#, Infinity è il risultato quando si divide per zero.

  4. Premere F5 o selezionare Debug>continua debug.

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

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

Completamento del codice

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

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:

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:

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:

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;
        }
    }
}

Passaggi successivi

L'esercitazione è stata completata. Per altre informazioni, continuare con il contenuto seguente: