Dela via


Självstudie: Utöka C#-konsolappen och felsöka i Visual Studio (del 2 av 2)

I del 2 i den här självstudieserien går du lite djupare in i visual studio-funktionerna för att skapa och felsöka de funktioner som du behöver för den dagliga utvecklingen. Dessa funktioner omfattar att hantera flera projekt, felsöka och referera till paket från tredje part. Du kör C#-konsolappen som du skapade i del 1 i den här självstudienoch utforskar några funktioner i Visual Studio Integrated Development Environment (IDE). Den här självstudien är del 2 i en självstudieserie i två delar.

I den här självstudien utför du följande uppgifter:

  • Lägg till ett andra projekt.
  • Referensbibliotek och lägg till paket.
  • Felsök koden.
  • Kontrollera den färdiga koden.

Förutsättningar

Om du vill gå igenom den här artikeln kan du använda någon av dessa kalkylatorappar:

Lägg till ett annat projekt

Verklig kod omfattar projekt som arbetar tillsammans i en lösning. Du kan lägga till ett klassbiblioteksprojekt i kalkylatorappen som innehåller vissa kalkylatorfunktioner.

I Visual Studio använder du menykommandot File>Add>New Project för att lägga till ett nytt projekt. Du kan också högerklicka på lösningen i Solution Explorer för att lägga till ett projekt från snabbmenyn.

  1. I Solution Explorerhögerklickar du på lösningsnoden och väljer Lägg till>Nytt projekt.

  2. I fönstret Lägg till ett nytt projekt skriver du klassbiblioteket i sökrutan. Välj projektmallen C# klassbibliotek och välj därefter Nästa.

    Skärmbild av val av projektmall för klassbibliotek.

  3. På skärmen Konfigurera ditt nya projekt skriver du projektnamnet CalculatorLibraryoch väljer sedan Nästa.

  4. Välj .NET 3.1 när du tillfrågas. Visual Studio skapar det nya projektet och lägger till det i lösningen.

    Skärmbild av Solution Explorer med projekt för biblioteksbiblioteket CalculatorLibrary tillagt.

  5. Byt namn på filen Class1.cs till CalculatorLibrary.cs. Om du vill byta namn på filen kan du högerklicka på namnet i Solution Explorer och välja Byt namn, välj namnet och tryck på F2eller välj namnet och välj igen för att skriva.

    Ett meddelande kan fråga om du vill byta namn på referenser till Class1 i filen. Det spelar ingen roll hur du svarar, eftersom du ersätter koden i ett framtida steg.

  6. Lägg nu till en projektreferens så att det första projektet kan använda API:er som det nya klassbiblioteket exponerar. Högerklicka på noden Beroenden i projektet Calculator och välj Lägg till projektreferens.

    Skärmbild av menyalternativet Lägg till projektreferens.

    Dialogrutan Reference Manager visas. I den här dialogrutan kan du lägga till referenser till andra projekt, sammansättningar och COM-DLL:er som dina projekt behöver.

  7. I dialogrutan Reference Manager markerar du kryssrutan för projektet CalculatorLibrary och väljer sedan OK.

    Skärmbild av dialogrutan Referenshanteraren.

    Projektreferensen visas under en nod Projects i Solution Explorer.

    Skärmbild av Solution Explorer med projektreferens.

  8. I Program.csväljer du klassen Calculator och all dess kod och trycker på Ctrl+X för att klippa ut den. I CalculatorLibrary.csklistrar du sedan in koden i CalculatorLibrary namnområdet.

    Lägg också till public före klassen Kalkylator för att exponera den utanför biblioteket.

    CalculatorLibrary.cs bör nu likna följande kod:

    // 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 har också en referens, men ett fel säger att Calculator.DoOperation-anropet inte löser problemet. Felet beror på att CalculatorLibrary finns i ett annat namnområde. För en fullständigt kvalificerad referens kan du lägga till CalculatorLibrary-namnområdet i Calculator.DoOperation-anropet i Program.cs:

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

    Du kan också prova att lägga till ett using-direktiv i början av Program.cs-filen:

    // Program.cs
    using CalculatorLibrary;
    

    Genom att lägga till using-direktivet kan du ta bort CalculatorLibrary namnområdet från anropswebbplatsen, men nu finns det en tvetydighet. Är Calculator klassen i CalculatorLibrary, eller är Calculator namnområdet?

    Lös tvetydigheten genom att byta namn på namnområdet från Calculator till CalculatorProgram i Program.cs.

    // Program.cs
    namespace CalculatorProgram
    
  1. I Solution Explorerhögerklickar du på lösningsnoden och väljer Lägg till>Nytt projekt.

  2. I fönstret Lägg till ett nytt projekt skriver du klassbiblioteket i sökrutan. Välj projektmallen C# klassbibliotek och välj därefter Nästa.

    Skärmbild av val av projektmall för klassbibliotek.

  3. På skärmen Konfigurera ditt nya projekt skriver du projektnamnet CalculatorLibraryoch väljer sedan Nästa.

  4. På skärmen Ytterligare information väljs .NET 8.0. Välj Skapa.

    Visual Studio skapar det nya projektet och lägger till det i lösningen.

    Skärmbild av Solution Explorer med projekt för biblioteksbiblioteket CalculatorLibrary tillagt.

  5. Byt namn på filen Class1.cs till CalculatorLibrary.cs. Om du vill byta namn på filen kan du högerklicka på namnet i Solution Explorer och välja Byt namn, välj namnet och tryck på F2eller välj namnet och välj igen för att skriva.

    Ett meddelande kan fråga om du vill byta namn på alla referenser till Class1 i filen. Det spelar ingen roll hur du svarar, eftersom du ersätter koden i ett framtida steg.

  6. Lägg nu till en projektreferens så att det första projektet kan använda API:er som det nya klassbiblioteket exponerar. Högerklicka på noden Beroenden i projektet Calculator och välj Lägg till projektreferens.

    Skärmbild av menyalternativet Lägg till projektreferens.

    Dialogrutan Reference Manager visas. I den här dialogrutan kan du lägga till referenser till andra projekt, sammansättningar och COM-DLL:er som dina projekt behöver.

  7. I dialogrutan Reference Manager markerar du kryssrutan för projektet CalculatorLibrary och väljer sedan OK.

    Skärmbild av dialogrutan Referenshanteraren.

    Projektreferensen visas under en nod Projects i Solution Explorer.

    Skärmbild av Solution Explorer med projektreferens.

  8. I Program.csväljer du klassen Calculator och all dess kod och trycker på Ctrl+X för att klippa ut den. I CalculatorLibrary.csklistrar du sedan in koden i CalculatorLibrary namnområdet.

    Lägg också till public före klassen Kalkylator för att exponera den utanför biblioteket.

    CalculatorLibrary.cs bör nu likna följande kod:

     // 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 har också en referens, men ett fel säger att Calculator.DoOperation-anropet inte löser problemet. Felet beror på att CalculatorLibrary finns i ett annat namnområde. För en fullständigt kvalificerad referens kan du lägga till CalculatorLibrary-namnområdet i Calculator.DoOperation-anropet i Program.cs:

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

    Du kan också prova att lägga till ett using-direktiv i början av Program.cs-filen:

    // Program.cs
    using CalculatorLibrary;
    

    Genom att lägga till using-direktivet kan du ta bort CalculatorLibrary-namnområdet från anropswebbplatsen.

    Om din Program.cs kod finns i namnområdet Calculator byter du namn på namnområdet från Calculator till CalculatorProgram för att ta bort tvetydighet mellan klassnamn och namnområdesnamn.

Referensbibliotek för .NET: Skriv till en logg

Du kan använda klassen .NET Trace för att lägga till en logg över alla åtgärder och skriva den till en textfil. Klassen Trace är också användbar för grundläggande utskriftsfelsökningstekniker. Klassen Trace finns i System.Diagnosticsoch använder System.IO klasser som StreamWriter.

  1. Börja med att lägga till using direktiv överst i CalculatorLibrary.cs:

    // CalculatorLibrary.cs
    using System.IO;
    using System.Diagnostics;
    
  2. Den här användningen av klassen Trace måste innehålla en referens för klassen, som den associerar med en filström. Det kravet innebär att kalkylatorn fungerar bättre som ett objekt, så lägg till en konstruktor i början av klassen Calculator i CalculatorLibrary.cs.

    Ta också bort nyckelordet static för att ändra metoden static DoOperation till en medlemsmetod.

    // 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. Lägg till loggutdata i varje beräkning. DoOperation bör nu se ut som följande kod:

    // 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. Tillbaka i Program.csflaggar nu en röd vågig understrykning det statiska anropet. Åtgärda felet genom att skapa en calculator variabel genom att lägga till följande kodrad precis före while (!endApp)-loopen:

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

    Ändra även DoOperation-anropet så att det refererar till objektet med namnet calculator i gemener. Koden är nu ett medlemsanrop i stället för ett anrop till en statisk metod.

    // Program.cs
    result = calculator.DoOperation(cleanNum1, cleanNum2, op);
    
  5. Kör appen igen. När du är klar högerklickar du på projektnoden Calculator och väljer Öppna mapp i Utforskaren.

  6. I Utforskaren navigerar du till utdatamappen under bin/Debug/net8.0 (eller vilken .NET-version du använder) och öppnar filen calculator.log. Utdata bör se ut ungefär så här:

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

Nu bör CalculatorLibrary.cs likna den här koden:

// 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 bör se ut som följande kod:

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

Du kan använda klassen .NET Trace för att lägga till en logg över alla åtgärder och skriva den till en textfil. Klassen Trace är också användbar för grundläggande utskriftsfelsökningstekniker. Klassen Trace finns i System.Diagnosticsoch använder System.IO klasser som StreamWriter.

  1. Börja med att lägga till using direktiv överst i CalculatorLibrary.cs:

    // CalculatorLibrary.cs
    using System.Diagnostics;
    
  2. Den här användningen av klassen Trace måste innehålla en referens för klassen, som den associerar med en filström. Det kravet innebär att kalkylatorn fungerar bättre som ett objekt, så lägg till en konstruktor i början av klassen Calculator i CalculatorLibrary.cs.

    Ta också bort nyckelordet static för att ändra metoden static DoOperation till en medlemsmetod.

    // 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. Lägg till loggutdata i varje beräkning. DoOperation bör nu se ut som följande kod:

    // 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. Tillbaka i Program.csflaggar nu en röd vågig understrykning det statiska anropet. Åtgärda felet genom att skapa en calculator variabel genom att lägga till följande kodrad precis före while (!endApp)-loopen:

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

    Ändra även DoOperation-anropet så att det refererar till objektet med namnet calculator i gemener. Koden är nu ett medlemsanrop i stället för ett anrop till en statisk metod.

    // Program.cs
    result = calculator.DoOperation(cleanNum1, cleanNum2, op);
    
  5. Kör appen igen. När du är klar högerklickar du på projektnoden Calculator och väljer Öppna mapp i Utforskaren.

  6. I Utforskaren går du till utdatamappen under bin/Debug/och öppnar filen calculator.log. Utdata bör se ut ungefär så här:

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

Nu bör CalculatorLibrary.cs likna den här koden:

// 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 bör se ut som följande kod:

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

Lägg till ett NuGet-paket: Skriv till en JSON-fil

För utdataåtgärder i JSON, ett populärt och portabelt format för lagring av objektdata, kan du referera till Newtonsoft.Json- NuGet-paketet. NuGet-paket är den primära distributionsmetoden för .NET-klassbibliotek.

  1. I Solution Explorerhögerklickar du på noden Beroenden för projektet CalculatorLibrary och väljer Hantera NuGet-paket.

    Skärmbild av Hantera NuGet-paket på snabbmenyn.

    Skärmbild av Hantera NuGet-paket på snabbmenyn.

    NuGet Package Manager öppnas.

    Skärmbild av NuGet Package Manager.

  2. Sök efter och välj Newtonsoft.Json--paketet och välj Installera.

    Skärmbild av Newtonsoft J SON NuGet-paketinformation i NuGet Package Manager.

    Visual Studio laddar ned paketet och lägger till det i projektet. Ett nytt element visas i noden Referenser i Solution Explorer.

    Skärmbild av Newtonsoft J SON NuGet-paketinformation i NuGet Package Manager.

    Om du uppmanas att godkänna ändringar väljer du OK.

    Visual Studio laddar ned paketet och lägger till det i projektet. En ny post i en Packages-nod visas i Solution Explorer.

    Lägg till ett using direktiv för Newtonsoft.Json i början av CalculatorLibrary.cs.

    // CalculatorLibrary.cs
    using Newtonsoft.Json;
    
  3. Skapa JsonWriter medlemsobjektet och ersätt Calculator konstruktorn med följande kod:

         // 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. Ändra DoOperation-metoden för att lägga till JSON-writer-koden:

         // 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. Lägg till en metod för att slutföra JSON-syntaxen när användaren har angett åtgärdsdata.

     // CalculatorLibrary.cs
     public void Finish()
     {
         writer.WriteEndArray();
         writer.WriteEndObject();
         writer.Close();
     }
    
  6. I slutet av Program.cslägger du till ett anrop till return;innan Finish:

         // Program.cs
             // Add call to close the JSON writer before return
             calculator.Finish();
             return;
         }
    
  7. Skapa och kör appen, och när du har angett några åtgärder stänger du appen genom att ange kommandot n.

  8. Öppna filen calculatorlog.json i Utforskaren. Du bör se något som liknar följande innehåll:

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

Felsökning: Ange och träffa en brytpunkt

Visual Studio-felsökningsprogrammet är ett kraftfullt verktyg. Felsökningsprogrammet kan gå igenom koden för att hitta den exakta punkten där det finns ett programmeringsfel. Sedan kan du förstå vilka korrigeringar du behöver göra och göra tillfälliga ändringar så att du kan fortsätta köra appen.

  1. I Program.csklickar du i marginalen till vänster om följande kodrad. Du kan också klicka på raden och välja F9, eller högerklicka på raden och välja Brytpunkt>Infoga brytpunkt.

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

    Den röda punkt som visas anger en brytpunkt. Du kan använda brytpunkter för att pausa din app och inspektera kod. Du kan ange en brytpunkt på valfri körbar kodrad.

    Skärmbild som visar hur du anger en brytpunkt.

  2. Skapa och kör appen. Ange följande värden för beräkningen:

    • För det första talet anger du 8.
    • För det andra talet anger du 0.
    • För operatören, låt oss ha lite kul. Ange d.

    Appen pausar där du skapade brytpunkten, vilket indikeras av den gula pekaren till vänster och den markerade koden. Den markerade koden har ännu inte körts.

    Skärmbild av att träffa en brytpunkt

    Nu när appen har inaktiverats kan du kontrollera programtillståndet.

Felsökning: Visa variabler

  1. Hovra över variabler som cleanNum1 och opi den markerade koden. Aktuella värden för dessa variabler, 8 respektive d, visas i Datatips.

    Skärmbild som visar hur du visar en DataTip.

    Vid felsökning är det ofta viktigt att kontrollera om variabler innehåller de värden som du förväntar dig för att åtgärda problem.

  2. I den nedre rutan tittar du på fönstret Locals. Om den är stängd väljer du Felsök>Windows>Locals för att öppna den.

    Fönstret Locals visar varje variabel som för närvarande finns i omfånget, tillsammans med dess värde och typ.

    Skärmdump av Lokaler-fönstret.

    Skärmdump av Lokaler-fönstret.

  3. Titta på fönstret Autos.

    Fönstret Autos liknar fönstret Locals, men visar variablerna direkt före och följer den aktuella kodraden där appen har pausats.

    Not

    Om du inte ser fönstret Autos, välj Felsöka>Windows>Autos för att öppna det.

Kör sedan kod i felsökaren ett steg i taget, vilket kallas stegning.

Felsökning: Stega igenom kod

  1. Tryck på F11eller välj Felsök>Steg in i.

    Med kommandot Step Into kör appen den aktuella instruktionen och går vidare till nästa körbara instruktion, vanligtvis nästa kodrad. Den gula pekaren till vänster anger alltid den aktuella instruktionen.

    Skärmbild av steg i kommando

    Du har precis gått in i metoden DoOperation i klassen Calculator.

  2. Om du vill få en hierarkisk vy över programflödet, titta i fönstret Anropsstack. Om den är stängd väljer du Felsök>Windows>Anropsstack för att öppna den.

    Skärmbild av anropsstacken

    Den här vyn visar den aktuella metoden Calculator.DoOperation, som anges av den gula pekaren. Den andra raden visar funktionen som anropade metoden från metoden Main i Program.cs.

    Fönstret Call Stack visar i vilken ordning metoder och funktioner anropas. Det här fönstret ger också åtkomst till många felsökningsfunktioner, till exempel Gå till källkod, från snabbmenyn.

  3. Tryck på F10eller välj Felsöka>Steg överflera gånger tills appen pausar switch-instruktionen.

    // CalculatorLibrary.cs
    switch (op)
    {
    

    Kommandot Step Over liknar kommandot Step Into, förutom att om den aktuella instruktionen anropar en funktion kör felsökningsprogrammet koden i funktionen och pausar inte körningen förrän funktionen returneras. Step Over är snabbare än Step Into om du inte är intresserad av en viss funktion.

  4. Tryck på F10 en gång till så att appen pausar på följande kodrad.

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

    Den här koden kontrollerar ett fall av division med noll. Om appen fortsätter genererar den ett allmänt undantag (ett fel), men du kanske vill prova något annat, som att visa det faktiska returnerade värdet i konsolen. Ett alternativ är att använda en felsökningsfunktion med namnet redigera och fortsätt för att göra ändringar i koden och sedan fortsätta felsökningen. Det finns dock ett annat trick för att tillfälligt ändra exekveringsflödet.

Felsökning: Testa en tillfällig ändring

  1. Välj den gula pekaren, som för närvarande är pausad på if (num2 != 0)-instruktionen, och dra den till följande instruktion:

    // CalculatorLibrary.cs
    result = num1 / num2;
    

    Om du drar pekaren här hoppar appen helt över if-instruktionen, så att du kan se vad som händer när du delar med noll.

  2. Tryck på F10 för att köra kodraden.

  3. Om du hovrar över variabeln result, visas värdet Infinity. I C#är Infinity resultatet när du delar med noll.

  4. Tryck på F5eller välj Felsök>Fortsätt felsöka.

    Oändlighetssymbolen visas i konsolen som ett resultat av matematisk åtgärd.

  5. Stäng appen korrekt genom att ange kommandot n.

Koden har slutförts

Här är den fullständiga koden för CalculatorLibrary.cs-filen när du har slutfört alla steg:

// 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();
        }
    }
}

Och här är koden för 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;
        }
    }
}

Här är den fullständiga koden för CalculatorLibrary.cs-filen när du har slutfört alla steg:

// 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();
        }
    }
}

Och här är koden för 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;
        }
    }
}

Nästa steg

Grattis till att du har slutfört den här handledningen! Om du vill veta mer fortsätter du med följande innehåll: