Udostępnij za pośrednictwem


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ęść 1 tego samouczkai 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 dodawanie pakietów.
  • Debugowanie kodu.
  • Sprawdź ukończony kod.

Warunki 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żyjesz polecenia menu Plik>Dodaj>Nowy projekt, aby dodać nowy projekt. Możesz również kliknąć rozwiązanie prawym przyciskiem myszy w eksploratorze rozwiązań , aby dodać projekt z menu kontekstowego.

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

  2. W oknie Dodaj nowy projekt wpisz biblioteka klas w polu wyszukiwania. Wybierz szablon projektu biblioteki klas języka C#, a następnie wybierz Dalej.

    Zrzut ekranu przedstawiający wybór szablonu projektu Biblioteka klas.

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

  4. Wybierz .NET 3.1, gdy zostaniesz o to poproszony. Program Visual Studio tworzy nowy projekt i dodaje go do rozwiązania.

    Zrzut ekranu Eksploratora rozwiązań z dodanym projektem biblioteki klas CalculatorLibrary.

  5. Zmień nazwę pliku Class1.cs na CalculatorLibrary.cs. Aby zmienić nazwę pliku, możesz kliknąć prawym przyciskiem myszy nazwę w eksploratorze rozwiązań i wybrać Zmień nazwę, wybierz nazwę i naciśnij F2lub wybierz nazwę i wybierz ponownie, aby wpisać.

    Komunikat może zapytać, czy chcesz zmienić nazwy 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 pozycję Dodaj odwołanie do projektu.

    zrzut ekranu przedstawiający element menu Dodaj odwołanie do projektu.

    Zostanie wyświetlone okno dialogowe Menedżera 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 Reference Manager zaznacz pole wyboru projektu CalculatorLibrary, a następnie wybierz pozycję OK.

    zrzut ekranu okna dialogowego Menedżer odwołań.

    Odwołanie do projektu jest wyświetlane w węźle Projects w Eksploratorze Rozwiązań .

    Zrzut ekranu Eksploratora rozwiązań z odwołaniem do projektu.

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

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

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

    // 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 również ma odwołanie, ale występuje błąd, który wskazuje, że wywołanie Calculator.DoOperation nie zostało rozwiązane. Błąd jest spowodowany tym, że CalculatorLibrary znajduje się w innej przestrzeni nazw. W przypadku w pełni kwalifikowanej referencji można dodać przestrzeń nazw CalculatorLibrary do wywołania Calculator.DoOperation w Program.cs:

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

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

    // Program.cs
    using CalculatorLibrary;
    

    Dodanie dyrektywy using może usunąć przestrzeń nazw CalculatorLibrary z miejsca wywołania, ale teraz istnieje niejednoznaczność. Czy Calculator to klasa w CalculatorLibrary, czy Calculator to przestrzeń nazw?

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

    // Program.cs
    namespace CalculatorProgram
    
  1. W eksploratorze rozwiązań kliknij prawym przyciskiem myszy węzeł rozwiązania i wybierz Dodaj>Nowy projekt.

  2. W oknie Dodaj nowy projekt wpisz biblioteka klas w polu wyszukiwania. Wybierz szablon projektu biblioteki klas języka C#, a następnie wybierz Dalej.

    Zrzut ekranu przedstawiający wybór szablonu projektu Biblioteka klas.

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

  4. Na ekranie Dodatkowe informacje jest wybrana opcja .NET 8.0. Wybierz pozycję Utwórz.

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

    Zrzut ekranu Eksploratora rozwiązań z dodanym projektem biblioteki klas CalculatorLibrary.

  5. Zmień nazwę pliku Class1.cs na CalculatorLibrary.cs. Aby zmienić nazwę pliku, możesz kliknąć prawym przyciskiem myszy nazwę w eksploratorze rozwiązań i wybrać Zmień nazwę, wybierz nazwę i naciśnij F2lub wybierz nazwę i wybierz ponownie, aby wpisać.

    Komunikat może zapytać, czy chcesz zmienić nazwę wszystkich 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 pozycję Dodaj odwołanie do projektu.

    zrzut ekranu przedstawiający element menu Dodaj odwołanie do projektu.

    Zostanie wyświetlone okno dialogowe Menedżera 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 Reference Manager zaznacz pole wyboru projektu CalculatorLibrary, a następnie wybierz pozycję OK.

    zrzut ekranu okna dialogowego Menedżer odwołań.

    Odwołanie do projektu jest wyświetlane w węźle Projects w Eksploratorze Rozwiązań .

    Zrzut ekranu Eksploratora rozwiązań z odwołaniem do projektu.

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

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

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

     // 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 również ma odwołanie, ale występuje błąd, który wskazuje, że wywołanie Calculator.DoOperation nie zostało rozwiązane. Błąd jest spowodowany tym, że CalculatorLibrary znajduje się w innej przestrzeni nazw. W przypadku w pełni kwalifikowanej referencji można dodać przestrzeń nazw CalculatorLibrary do wywołania Calculator.DoOperation w Program.cs:

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

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

    // Program.cs
    using CalculatorLibrary;
    

    Dodanie dyrektywy using powinno umożliwić usunięcie przestrzeni nazw CalculatorLibrary z miejsca wywołania.

    Jeśli kod Program.cs znajduje się w przestrzeni nazw Calculator, zmień nazwę przestrzeni nazw z Calculator na CalculatorProgram, aby usunąć niejednoznaczność między nazwą klasy a nazwą przestrzeni nazw.

Biblioteki referencyjne .NET: Zapisywanie do logu

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

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

    // CalculatorLibrary.cs
    using System.IO;
    using System.Diagnostics;
    
  2. To użycie klasy Trace 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 klasy Calculator w CalculatorLibrary.cs.

    Usuń także słowo kluczowe static, aby przekształcić metodę statyczną DoOperation w metodę składową.

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

    // 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. Powrót do Program.cs, czerwone faliste podkreślenie teraz wskazuje na wywołanie statyczne. Aby rozwiązać ten problem, utwórz zmienną calculator, dodając następujący wiersz kodu tuż przed pętlą while (!endApp):

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

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

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

  6. W Eksploratorze plików przejdź do folderu wyjściowego w obszarze bin/Debug/net8.0 (lub dowolnej używanej wersji platformy .NET) i otwórz plik calculator.log. Dane wyjściowe powinny wyglądać mniej więcej tak:

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

W tym momencie CalculatorLibrary.cs powinny wyglądać podobnie do tego kodu:

// 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 powinien wyglądać podobnie do następującego kodu:

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

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

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

    // CalculatorLibrary.cs
    using System.Diagnostics;
    
  2. To użycie klasy Trace 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 klasy Calculator w CalculatorLibrary.cs.

    Usuń także słowo kluczowe static, aby przekształcić metodę statyczną DoOperation w metodę składową.

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

    // 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. Powrót do Program.cs, czerwone faliste podkreślenie teraz wskazuje na wywołanie statyczne. Aby rozwiązać ten problem, utwórz zmienną calculator, dodając następujący wiersz kodu tuż przed pętlą while (!endApp):

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

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

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

  6. W Eksploratorze plików przejdź do folderu wyjściowego w obszarze bin/Debug/i otwórz plik calculator.log. Dane wyjściowe powinny wyglądać mniej więcej tak:

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

W tym momencie CalculatorLibrary.cs powinny wyglądać podobnie do tego kodu:

// 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 powinien wyglądać podobnie do następującego kodu:

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

Dodaj pakiet NuGet: zapisz w pliku JSON

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

  1. W eksploratorze rozwiązań kliknij prawym przyciskiem myszy węzeł zależności dla projektu CalculatorLibrary, a następnie wybierz Zarządzaj pakietami NuGet.

    zrzut ekranu przedstawiający zarządzanie pakietami NuGet w menu skrótów.

    zrzut ekranu przedstawiający zarządzanie pakietami NuGet w menu skrótów.

    Zostanie otwarty Menedżer pakietów NuGet.

    zrzut ekranu przedstawiający Menedżera pakietów NuGet.

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

    zrzut ekranu przedstawiający informacje o pakiecie NuGet Newtonsoft J SON w Menedżerze pakietów NuGet.

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

    zrzut ekranu przedstawiający informacje o pakiecie NuGet Newtonsoft J SON w Menedżerze pakietów NuGet.

    Jeśli zostanie wyświetlony monit o zaakceptowanie zmian, wybierz pozycję OK.

    Program Visual Studio pobiera pakiet i dodaje go do projektu. Nowy wpis pojawia się w węźle Packages w eksploratorze rozwiązań .

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

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

         // 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. Zmodyfikuj metodę DoOperation, aby dodać kod writer JSON:

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

     // CalculatorLibrary.cs
     public void Finish()
     {
         writer.WriteEndArray();
         writer.WriteEndObject();
         writer.Close();
     }
    
  6. Na końcu Program.cs, przed return;, dodaj wywołanie funkcji Finish:

         // Program.cs
             // 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 polecenie n.

  8. Otwórz plik calculatorlog.json w Eksploratorze 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: ustaw punkt przerwania i traf w niego

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 Program.cskliknij w margines po lewej stronie poniższego wiersza kodu. Możesz również kliknąć linię i wybrać pozycję F9lub kliknąć linię prawym przyciskiem myszy i wybrać punkt przerwania>Wstaw punkt przerwania.

    // Program.cs
    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.

    Zrzut ekranu przedstawiający ustawianie punktu przerwania.

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

    • Dla pierwszej liczby wprowadź 8.
    • W przypadku drugiej liczby wprowadź 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.

    Zrzut ekranu przedstawiający punktu przerwania

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

Debugowanie: Wyświetlanie zmiennych

  1. W wyróżnionym kodzie najedź kursorem na zmienne, takie jak cleanNum1 i op. Bieżące wartości tych zmiennych, 8 i d, są wyświetlane we wskazówkach danych.

    Zrzut ekranu przedstawiający wyświetlanie etykietki danych.

    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ęte, wybierz Debug>Windows>Lokalne, aby je otworzyć.

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

    zrzut ekranu przedstawiający okno Ustawienia lokalne.

    zrzut ekranu przedstawiający okno Ustawienia lokalne.

  3. Spójrz na okno Autos.

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

    Notatka

    Jeśli nie widzisz okna Autos, wybierz pozycję Debugowanie>Okna>Autos, aby je otworzyć.

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

Debugowanie: przechodzenie krok po kroku przez kod

  1. Naciśnij F11lub wybierz Debug>Wejdź do.

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

    Zrzut ekranu przedstawiający krok do polecenia

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

  2. Aby uzyskać hierarchiczny obraz przepływu programu, zajrzyj do okna Stosu Wywołań . Jeśli jest zamknięte, wybierz Debug>Windows>stos wywołań, aby go otworzyć.

    zrzut ekranu przedstawiający stos wywołań

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

    W oknie stos wywołań przedstawiono 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 F10lub wybierz Debug>Step Over, kilka razy, aż aplikacja zatrzyma się na instrukcji switch.

    // CalculatorLibrary.cs
    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 przez jest szybszy niż Krok do wewnątrz, jeśli nie interesuje Cię określona funkcja.

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

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

    Ten kod sprawdza przypadek dzielenia przez zero. Jeśli aplikacja będzie nadal działać, wyrzuca 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. 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, który jest obecnie wstrzymany na instrukcji if (num2 != 0), a następnie przeciągnij go do następującej instrukcji:

    // CalculatorLibrary.cs
    result = num1 / num2;
    

    Przeciągnięcie wskaźnika powoduje, że aplikacja całkowicie pomija instrukcję if, żeby zobaczyć, co się stanie po podzieleniu przez zero.

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

  3. Jeśli umieścisz wskaźnik myszy na zmiennej result, zostanie wyświetlona wartość Infinity. W języku C# nieskończoność jest wynikiem dzielenia przez zero.

  4. Naciśnij F5lub wybierz pozycję Debugowanie>Kontynuuj debugowanie.

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

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

Kod kompletny

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

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

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

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

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

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

Następne kroki

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