Samouczek: rozszerzanie aplikacji konsolowej języka C# i debugowanie w programie Visual Studio (część 2 z 2)

W części 2 tej serii samouczków bardziej szczegółowo poznasz funkcje kompilacji i debugowania programu Visual Studio potrzebne do codziennego programowania. Te funkcje obejmują zarządzanie wieloma projektami, debugowaniem i odwoływaniem się do pakietów innych firm. Uruchom aplikację konsolową języka C# utworzoną w części 1 tego samouczka i zapoznasz się z niektórymi funkcjami zintegrowanego środowiska projektowego (IDE) programu Visual Studio. Ten samouczek jest częścią 2 dwuczęściowej serii samouczków.

W tym samouczku wykonasz następujące zadania:

  • Dodaj drugi projekt.
  • Biblioteki referencyjne i dodaj pakiety.
  • Debugowanie kodu.
  • Sprawdź ukończony kod.

Wymagania wstępne

Aby pracować z tym artykułem, możesz użyć jednej z następujących aplikacji kalkulatora:

Dodawanie innego projektu

Rzeczywisty kod obejmuje projekty współpracujące ze sobą w rozwiązaniu. Projekt biblioteki klas można dodać do aplikacji kalkulatora, która udostępnia niektóre funkcje kalkulatora.

W programie Visual Studio użyj polecenia menu Plik>dodaj>nowy projekt, aby dodać nowy projekt. Możesz również kliknąć rozwiązanie prawym przyciskiem myszy w Eksplorator rozwiązań, aby dodać projekt z menu kontekstowego.

  1. W Eksplorator rozwiązań kliknij prawym przyciskiem myszy węzeł rozwiązania i wybierz polecenie Dodaj>nowy projekt.

  2. W oknie Dodawanie nowego projektu wpisz bibliotekę klas w polu Wyszukaj. Wybierz szablon projektu Biblioteka klas języka C#, a następnie wybierz przycisk Dalej.

    Screenshot of Class Library project template selection.

  3. Na ekranie Konfigurowanie nowego projektu wpisz nazwę projektu CalculatorLibrary, a następnie wybierz pozycję Dalej.

  4. Wybierz platformę .NET 3.1 po wyświetleniu monitu. Program Visual Studio tworzy nowy projekt i dodaje go do rozwiązania.

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

  5. Zmień nazwę pliku Class1.cs na CalculatorLibrary.cs. Aby zmienić nazwę pliku, możesz kliknąć prawym przyciskiem myszy nazwę w Eksplorator rozwiązań i wybrać polecenie Zmień nazwę, wybrać nazwę i nacisnąć klawisz F2 lub wybrać nazwę i wybrać ponownie, aby wpisać.

    Komunikat może zapytać, czy chcesz zmienić nazwę odwołań na Class1 w pliku. Nie ma znaczenia, jak odpowiadasz, ponieważ zastąpisz kod w przyszłym kroku.

  6. Teraz dodaj odwołanie do projektu, aby pierwszy projekt mógł używać interfejsów API udostępnianych przez nową bibliotekę klas. Kliknij prawym przyciskiem myszy węzeł Zależności w projekcie Kalkulator i wybierz polecenie Dodaj odwołanie do projektu.

    Screenshot of the Add Project Reference menu item.

    Zostanie wyświetlone okno dialogowe Menedżer odwołań. W tym oknie dialogowym można dodawać odwołania do innych projektów, zestawów i bibliotek DLL com potrzebnych w projektach.

  7. W oknie dialogowym Menedżer odwołań zaznacz pole wyboru projektu CalculatorLibrary, a następnie wybierz przycisk OK.

    Screenshot of the Reference Manager dialog box.

    Odwołanie do projektu zostanie wyświetlone w węźle Projekty w Eksplorator rozwiązań.

    Screenshot of Solution Explorer with project reference.

  8. W pliku Program.cs wybierz klasę Calculator i cały jego kod, a następnie naciśnij klawisze Ctrl+X, aby go wyciąć. Następnie w pliku CalculatorLibrary.cs wklej kod do CalculatorLibrary przestrzeni nazw.

    public Dodaj również przed klasą Calculator, aby uwidocznić ją poza biblioteką.

    Plik CalculatorLibrary.cs powinien teraz wyglądać podobnie do następującego kodu:

    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. Plik Program.cs zawiera również odwołanie, ale błąd wskazuje, że wywołanie nie rozwiązuje problemu Calculator.DoOperation . Błąd jest spowodowany tym, że CalculatorLibrary znajduje się w innej przestrzeni nazw. W przypadku w pełni kwalifikowanego odwołania można dodać CalculatorLibrary przestrzeń nazw do wywołania Calculator.DoOperation :

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

    Możesz też spróbować dodać dyrektywę using na początku pliku:

    using CalculatorLibrary;
    

    using Dodanie dyrektywy powinno umożliwić usunięcie CalculatorLibrary przestrzeni nazw z witryny wywołania, ale teraz istnieje niejednoznaczność. Czy Calculator klasa w elemecie CalculatorLibrary, czy jest Calculator przestrzenią nazw?

    Aby rozwiązać niejednoznaczność, zmień nazwę przestrzeni nazw z Calculator na CalculatorProgram w pliku Program.cs.

    namespace CalculatorProgram
    
  1. W Eksplorator rozwiązań kliknij prawym przyciskiem myszy węzeł rozwiązania i wybierz polecenie Dodaj>nowy projekt.

  2. W oknie Dodawanie nowego projektu wpisz bibliotekę klas w polu Wyszukaj. Wybierz szablon projektu Biblioteka klas języka C#, a następnie wybierz przycisk Dalej.

    Screenshot of Class Library project template selection.

  3. Na ekranie Konfigurowanie nowego projektu wpisz nazwę projektu CalculatorLibrary, a następnie wybierz pozycję Dalej.

  4. Na ekranie Dodatkowe informacje wybrano pozycję .NET 8.0. Wybierz pozycję Utwórz.

    Program Visual Studio tworzy nowy projekt i dodaje go do rozwiązania.

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

  5. Zmień nazwę pliku Class1.cs na CalculatorLibrary.cs. Aby zmienić nazwę pliku, możesz kliknąć prawym przyciskiem myszy nazwę w Eksplorator rozwiązań i wybrać polecenie Zmień nazwę, wybrać nazwę i nacisnąć klawisz F2 lub wybrać nazwę i wybrać ponownie, aby wpisać.

    Komunikat może zapytać, czy chcesz zmienić nazwę wszystkich odwołań do Class1 w pliku. Nie ma znaczenia, jak odpowiadasz, ponieważ zastąpisz kod w przyszłym kroku.

  6. Teraz dodaj odwołanie do projektu, aby pierwszy projekt mógł używać interfejsów API udostępnianych przez nową bibliotekę klas. Kliknij prawym przyciskiem myszy węzeł Zależności w projekcie Kalkulator i wybierz polecenie Dodaj odwołanie do projektu.

    Screenshot of the Add Project Reference menu item.

    Zostanie wyświetlone okno dialogowe Menedżer odwołań. W tym oknie dialogowym można dodawać odwołania do innych projektów, zestawów i bibliotek DLL com potrzebnych w projektach.

  7. W oknie dialogowym Menedżer odwołań zaznacz pole wyboru projektu CalculatorLibrary, a następnie wybierz przycisk OK.

    Screenshot of the Reference Manager dialog box.

    Odwołanie do projektu zostanie wyświetlone w węźle Projekty w Eksplorator rozwiązań.

    Screenshot of Solution Explorer with project reference.

  8. W pliku Program.cs wybierz klasę Calculator i cały jego kod, a następnie naciśnij klawisze Ctrl+X, aby go wyciąć. Następnie w pliku CalculatorLibrary.cs wklej kod do CalculatorLibrary przestrzeni nazw.

    public Dodaj również przed klasą Calculator, aby uwidocznić ją poza biblioteką.

    Plik CalculatorLibrary.cs powinien teraz wyglądać podobnie do następującego kodu:

     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. Plik Program.cs zawiera również odwołanie, ale błąd wskazuje, że wywołanie nie rozwiązuje problemu Calculator.DoOperation . Błąd jest spowodowany tym, że CalculatorLibrary znajduje się w innej przestrzeni nazw. W przypadku w pełni kwalifikowanego odwołania można dodać CalculatorLibrary przestrzeń nazw do wywołania Calculator.DoOperation :

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

    Możesz też spróbować dodać dyrektywę using na początku pliku:

    using CalculatorLibrary;
    

    using Dodanie dyrektywy powinno umożliwić usunięcie CalculatorLibrary przestrzeni nazw z witryny wywołania, ale teraz istnieje niejednoznaczność. Czy Calculator klasa w elemecie CalculatorLibrary, czy jest Calculator przestrzenią nazw?

    Aby rozwiązać niejednoznaczność, zmień nazwę przestrzeni nazw z Calculator na CalculatorProgram w pliku Program.cs.

    namespace CalculatorProgram
    

Dokumentacja bibliotek platformy .NET: zapisywanie w dzienniku

Możesz użyć klasy .NET Trace , aby dodać dziennik wszystkich operacji i zapisać go w pliku tekstowym. Klasa jest również przydatna Trace w przypadku podstawowych technik debugowania wydruku. Klasa Trace jest w System.Diagnosticsklasie i używa System.IO klas takich jak StreamWriter.

  1. Zacznij od dodania using dyrektyw w górnej części pliku CalculatorLibrary.cs:

    using System.IO;
    using System.Diagnostics;
    
  2. To użycie Trace klasy musi zawierać odwołanie do klasy, którą kojarzy z strumieniem plików. To wymaganie oznacza, że kalkulator działa lepiej jako obiekt, dlatego dodaj konstruktor na początku Calculator klasy w pliku CalculatorLibrary.cs.

    Usuń również słowo kluczowe , static aby zmienić metodę statyczną DoOperation na metodę składową.

    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. Dodaj dane wyjściowe dziennika do każdego obliczenia. DoOperation powinien teraz wyglądać podobnie do następującego kodu:

    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. Po powrocie do pliku Program.cs czerwone podkreślenie zwija się teraz flaguje wywołanie statyczne. Aby naprawić błąd, utwórz zmienną calculator , dodając następujący wiersz kodu tuż przed pętlą while (!endApp) :

    Calculator calculator = new Calculator();
    

    Zmodyfikuj również lokację wywołania, DoOperation aby odwoływać się do obiektu o nazwie calculator w małych literach. Kod jest teraz wywołaniem elementu członkowskiego, a nie wywołaniem metody statycznej.

    result = calculator.DoOperation(cleanNum1, cleanNum2, op);
    
  5. Ponownie uruchom aplikację. Po zakończeniu kliknij prawym przyciskiem myszy węzeł projektu Kalkulator i wybierz polecenie Otwórz folder w Eksplorator plików.

  6. W Eksplorator plików przejdź do folderu wyjściowego w obszarze bin/Debug/, a następnie otwórz plik calculator.log. Dane wyjściowe powinny wyglądać następująco:

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

W tym momencie plik CalculatorLibrary.cs powinien przypominać następujący kod:

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

Plik Program.cs powinien wyglądać podobnie do następującego kodu:

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

Możesz użyć klasy .NET Trace , aby dodać dziennik wszystkich operacji i zapisać go w pliku tekstowym. Klasa jest również przydatna Trace w przypadku podstawowych technik debugowania wydruku. Klasa Trace jest w System.Diagnosticsklasie i używa System.IO klas takich jak StreamWriter.

  1. Zacznij od dodania using dyrektyw w górnej części pliku CalculatorLibrary.cs:

    using System.Diagnostics;
    
  2. To użycie Trace klasy musi zawierać odwołanie do klasy, którą kojarzy z strumieniem plików. To wymaganie oznacza, że kalkulator działa lepiej jako obiekt, dlatego dodaj konstruktor na początku Calculator klasy w pliku CalculatorLibrary.cs.

    Usuń również słowo kluczowe , static aby zmienić metodę statyczną DoOperation na metodę składową.

    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. Dodaj dane wyjściowe dziennika do każdego obliczenia. DoOperation powinien teraz wyglądać podobnie do następującego kodu:

    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. Po powrocie do pliku Program.cs czerwone podkreślenie zwija się teraz flaguje wywołanie statyczne. Aby naprawić błąd, utwórz zmienną calculator , dodając następujący wiersz kodu tuż przed pętlą while (!endApp) :

    Calculator calculator = new Calculator();
    

    Zmodyfikuj również lokację wywołania, DoOperation aby odwoływać się do obiektu o nazwie calculator w małych literach. Kod jest teraz wywołaniem elementu członkowskiego, a nie wywołaniem metody statycznej.

    result = calculator.DoOperation(cleanNum1, cleanNum2, op);
    
  5. Ponownie uruchom aplikację. Po zakończeniu kliknij prawym przyciskiem myszy węzeł projektu Kalkulator i wybierz polecenie Otwórz folder w Eksplorator plików.

  6. W Eksplorator plików przejdź do folderu wyjściowego w obszarze bin/Debug/, a następnie otwórz plik calculator.log. Dane wyjściowe powinny wyglądać następująco:

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

W tym momencie plik CalculatorLibrary.cs powinien przypominać następujący kod:

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

Plik Program.cs powinien wyglądać podobnie do następującego kodu:

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

Dodawanie pakietu NuGet: zapisywanie w pliku JSON

Aby wykonać operacje wyjściowe w formacie JSON, popularnym i przenośnym formacie do przechowywania danych obiektów, możesz odwołać się do pakietu NuGet Newtonsoft.Json . Pakiety NuGet to podstawowa metoda dystrybucji bibliotek klas platformy .NET.

  1. W Eksplorator rozwiązań kliknij prawym przyciskiem myszy węzeł Zależności dla projektu CalculatorLibrary i wybierz pozycję Zarządzaj pakietami NuGet.

    Screenshot of Manage NuGet Packages on the shortcut menu.

    Screenshot of Manage NuGet Packages on the shortcut menu.

    Zostanie otwarty Menedżer pakietów NuGet.

    Screenshot of the NuGet Package Manager.

  2. Wyszukaj i wybierz pakiet Newtonsoft.Json , a następnie wybierz pozycję Zainstaluj.

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

    Program Visual Studio pobiera pakiet i dodaje go do projektu. Nowy wpis zostanie wyświetlony w węźle Odwołania w Eksplorator rozwiązań.

    Screenshot of Newtonsoft J SON NuGet package information in the NuGet Package Manager. Jeśli zostanie wyświetlony monit o zaakceptowanie zmian, wybierz przycisk OK.

    Program Visual Studio pobiera pakiet i dodaje go do projektu. Nowy wpis zostanie wyświetlony w węźle Pakiety w Eksplorator rozwiązań.

    Dodaj dyrektywę using na Newtonsoft.Json początku pliku CalculatorLibrary.cs.

    using Newtonsoft.Json;
    
  3. JsonWriter Utwórz obiekt członkowski i zastąp Calculator konstruktor następującym kodem:

         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. Zmodyfikuj metodę , DoOperation aby dodać kod 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. Dodaj metodę, aby zakończyć składnię JSON po zakończeniu wprowadzania danych operacji przez użytkownika.

     public void Finish()
     {
         writer.WriteEndArray();
         writer.WriteEndObject();
         writer.Close();
     }
    
  6. Na końcu pliku Program.cs dodaj return;wywołanie do Finishpliku :

             // Add call to close the JSON writer before return
             calculator.Finish();
             return;
         }
    
  7. Skompiluj i uruchom aplikację, a po zakończeniu wprowadzania kilku operacji zamknij aplikację, wprowadzając n polecenia.

  8. Otwórz plik calculatorlog.json w Eksplorator plików. Powinna zostać wyświetlona zawartość podobna do następującej:

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

Debugowanie: ustawianie i trafienie punktu przerwania

Debuger programu Visual Studio to zaawansowane narzędzie. Debuger może przejść przez kod, aby znaleźć dokładny punkt, w którym wystąpił błąd programowania. Następnie możesz zrozumieć, jakie poprawki należy wprowadzić, i wprowadzić tymczasowe zmiany, aby móc kontynuować uruchamianie aplikacji.

  1. W pliku Program.cs kliknij w rynnie po lewej stronie następującego wiersza kodu. Możesz również kliknąć wiersz i wybrać klawisz F9 lub kliknąć wiersz prawym przyciskiem myszy i wybrać pozycję Punkt przerwania Wstaw punkt> przerwania.

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

    Zostanie wyświetlona czerwona kropka wskazująca punkt przerwania. Możesz użyć punktów przerwania, aby wstrzymać aplikację i sprawdzić kod. Punkt przerwania można ustawić na dowolnym wykonywalnym wierszu kodu.

    Screenshot that shows setting a breakpoint.

  2. Skompiluj i uruchom aplikację. Wprowadź następujące wartości dla obliczenia:

    • Dla pierwszej liczby wprowadź wartość 8.
    • W przypadku drugiej liczby wprowadź wartość 0.
    • Dla operatora bawmy się dobrze. Wprowadź d.

    Aplikacja zawiesza się w miejscu utworzenia punktu przerwania, który jest wskazywany przez żółty wskaźnik po lewej stronie i wyróżniony kod. Wyróżniony kod nie został jeszcze wykonany.

    Screenshot of hitting a breakpoint

    Teraz po wstrzymaniu aplikacji możesz sprawdzić stan aplikacji.

Debugowanie: Wyświetlanie zmiennych

  1. W wyróżnionym kodzie umieść kursor na zmiennych, takich jak cleanNum1 i op. Bieżące wartości tych zmiennych 8 i d odpowiednio są wyświetlane w obszarze Dane Wskazówki.

    Screenshot that shows viewing a DataTip.

    Podczas debugowania sprawdź, czy zmienne przechowują oczekiwane wartości, często ma kluczowe znaczenie dla rozwiązywania problemów.

  2. W dolnym okienku przyjrzyj się oknie Ustawienia lokalne . Jeśli jest zamknięta, wybierz pozycję Debuguj>ustawienia lokalne systemu Windows>, aby go otworzyć.

    W oknie Ustawienia lokalne jest wyświetlana każda zmienna, która jest obecnie w zakresie, wraz z jego wartością i typem.

    Screenshot of the Locals window.

    Screenshot of the Locals window.

  3. Spójrz na okno Autos (Autos ).

    Okno Autos jest podobne do okna Ustawienia lokalne , ale pokazuje zmienne bezpośrednio poprzedzające i postępując zgodnie z bieżącym wierszem kodu, w którym aplikacja jest wstrzymana.

    Uwaga

    Jeśli nie widzisz okna Automatyczne, wybierz pozycję Debuguj>autos windows>, aby go otworzyć.

Następnie wykonaj kod w jednej instrukcji debugera, która jest nazywana krokiem.

Debugowanie: przechodzenie przez kod

  1. Naciśnij klawisz F11 lub wybierz pozycję Debuguj>krok do.

    Za pomocą polecenia Krok do aplikacja wykonuje bieżącą instrukcję i przechodzi do następnej instrukcji wykonywalnej, zwykle w następnym wierszu kodu. Żółty wskaźnik po lewej stronie zawsze wskazuje bieżącą instrukcję.

    Screenshot of step into command

    Właśnie wszedłeś do DoOperation metody w Calculator klasie .

  2. Aby uzyskać hierarchiczny wygląd przepływu programu, zapoznaj się z oknem stosu wywołań . Jeśli jest zamknięty, wybierz pozycję Debuguj>stos wywołań systemu Windows>, aby go otworzyć.

    Screenshot of the call stack

    Ten widok przedstawia bieżącą Calculator.DoOperation metodę wskazywaną przez żółty wskaźnik. Drugi wiersz przedstawia funkcję, która nazwała metodę , z Main metody w pliku Program.cs.

    W oknie Stos wywołań jest wyświetlana kolejność wywoływania metod i funkcji. To okno zapewnia również dostęp do wielu funkcji debugera, takich jak Przejdź do kodu źródłowego, z menu skrótów.

  3. Naciśnij klawisz F10 lub wybierz pozycję Debuguj>krok po kroku, kilka razy, aż aplikacja zostanie wstrzymana w instrukcji .switch

    switch (op)
    {
    

    Polecenie Step Over jest podobne do polecenia Step Into, z tą różnicą, że jeśli bieżąca instrukcja wywołuje funkcję, debuger uruchamia kod w funkcji i nie zawiesza wykonywania, dopóki funkcja nie powróci. Krok do kroku jest szybszy niż Krok do, jeśli nie interesuje Cię określona funkcja.

  4. Naciśnij klawisz F10 jeszcze raz, aby aplikacja wstrzymała się w następującym wierszu kodu.

    if (num2 != 0)
    {
    

    Ten kod sprawdza wielkość liter z podziałem przez zero. Jeśli aplikacja będzie nadal występować, zgłasza ogólny wyjątek (błąd), ale możesz spróbować wykonać inne czynności, na przykład wyświetlenie rzeczywistej zwróconej wartości w konsoli programu . Jedną z opcji jest użycie funkcji debugera o nazwie edit-and-continue , aby wprowadzić zmiany w kodzie, a następnie kontynuować debugowanie. Istnieje jednak inna sztuczka, aby tymczasowo zmodyfikować przepływ wykonywania.

Debugowanie: testowanie tymczasowej zmiany

  1. Wybierz żółty wskaźnik, obecnie wstrzymany w instrukcji if (num2 != 0) i przeciągnij go do następującej instrukcji:

    result = num1 / num2;
    

    Przeciągnięcie wskaźnika powoduje całkowite pominięcie if instrukcji przez aplikację, dzięki czemu możesz zobaczyć, co się stanie po podzieleniu przez zero.

  2. Naciśnij klawisz F10 , aby wykonać wiersz kodu.

  3. Po umieszczeniu wskaźnika myszy na zmiennej result zostanie wyświetlona wartość Nieskończoność. W języku C# nieskończoność jest wynikiem dzielenia przez zero.

  4. Naciśnij klawisz F5 lub wybierz pozycję Debuguj>kontynuuj debugowanie.

    Symbol nieskończoności pojawia się w konsoli w wyniku operacji matematycznej.

  5. Zamknij aplikację prawidłowo, wprowadzając n polecenia.

Ukończono kod

Oto kompletny kod pliku CalculatorLibrary.cs po wykonaniu wszystkich kroków:

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

Oto kod pliku 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;
        }
    }
}

Oto kompletny kod pliku CalculatorLibrary.cs po wykonaniu wszystkich kroków:

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

Oto kod pliku 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;
        }
    }
}

Następne kroki

Gratulujemy ukończenia tego samouczka! Aby dowiedzieć się więcej, kontynuuj pracę z następującą zawartością: