Tutorial: Erweitern der C#-Konsolen-App und Debuggen in Visual Studio (Teil 2 von 2)

In Teil 2 dieser Tutorial-Serie beschäftigen Sie sich etwas ausführlicher mit den Build- und Debugfunktionen von Visual Studio, die Sie für die tägliche Entwicklung benötigen. Zu diesen Features gehören das Verwalten mehrerer Projekte, das Debuggen und das Verweisen auf Drittanbieterpakete. Sie führen die C#-Konsolen-App aus, die Sie in Teil 1 dieses Tutorials erstellt haben, und lernen einige Features der integrierten Visual Studio-Entwicklungsumgebung (IDE) kennen. Dieses Tutorial ist der zweite Teil einer zweiteiligen Reihe.

In diesem Tutorial führen Sie die folgenden Aufgaben durch:

  • Hinzufügen eines zweiten Projekts.
  • Verweisen auf Bibliotheken und Hinzufügen von Paketen
  • Debuggen Sie Ihren Code.
  • Überprüfen des fertiggestellten Codes.

Voraussetzungen

Um diesen Artikel durcharbeiten zu können, können Sie eine der folgenden Rechner-Apps verwenden:

Hinzufügen eines weiteren Projekts

In der Praxis umfasst Code Projekte, die in einer Projektmappe zusammenarbeiten. Sie können Ihrer Rechner-App ein Klassenbibliotheksprojekt hinzufügen, das einige Rechnerfunktionen bietet.

In Visual Studio verwenden Sie den Menübefehl Datei>Hinzufügen>Neues Projekt, um ein neues Projekt hinzuzufügen. Alternativ können Sie im Projektmappen-Explorer mit der rechten Maustaste auf die Projektmappe klicken, um ein Projekt aus dem Kontextmenü hinzuzufügen.

  1. Klicken Sie im Projektmappen-Explorermit der rechten Maustaste auf den Projektmappenknoten, und wählen Sie Hinzufügen>Neues Projekt.

  2. Geben Sie auf im Fenster Neues Projekt hinzufügenclass library (Klassenbibliothek) in das Suchfeld ein. Wählen Sie die C#-Projektvorlage Klassenbibliothek und dann Weiter aus.

    Screenshot of Class Library project template selection.

  3. Geben Sie im Dialogfeld Neues Projekt konfigurieren den Projektnamen CalculatorLibrary ein, und klicken Sie dann auf Weiter.

  4. Wenn Sie dazu aufgefordert werden, wählen Sie „.NET 3.1“ aus. Visual Studio erstellt das neue Projekt und fügt es zur Projektmappe hinzu.

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

  5. Benennen Sie die Datei Class1.cs in CalculatorLibrary.cs um. Um die Datei umzubenennen, können Sie im Projektmappen-Explorer mit der rechten Maustaste auf den Namen klicken und Umbenennen auswählen, den Namen auswählen und F2 drücken, oder den Namen auswählen und erneut auswählen, um die Eingabe zu ermöglichen.

    In einer Meldung wird möglicherweise gefragt, ob Sie Verweise auf Class1 in der Datei umbenennen möchten. Es spielt keine Rolle, wie Sie antworten, da Sie den Code in einem zukünftigen Schritt ersetzen.

  6. Fügen Sie jetzt einen Projektverweis hinzu, damit das erste Projekt die APIs nutzen kann, die von der neuen Klassenbibliothek zur Verfügung gestellt werden. Klicken Sie mit der rechten Maustaste im ersten Projekt auf den Knoten Abhängigkeiten im Calculator-Projekt, und wählen Sie dann Projektverweis hinzufügen aus.

    Screenshot of the Add Project Reference menu item.

    Das Dialogfeld Verweis-Manager wird angezeigt. In diesem Dialogfeld können Sie Verweise auf andere Projekte sowie Assemblys und COM-DLLs hinzufügen, die Ihre Projekte benötigen.

  7. Aktivieren Sie im Dialogfeld Verweis-Manager das Kontrollkästchen für das Projekt CalculatorLibrary, und klicken Sie dann auf OK.

    Screenshot of the Reference Manager dialog box.

    Der Projektverweis wird unter dem Knoten Projekte im Projektmappen-Explorer angezeigt.

    Screenshot of Solution Explorer with project reference.

  8. Wählen Sie in der Datei Program.cs die Klasse Calculator und ihren gesamten Code aus, und drücken Sie STRG+X, um alles auszuschneiden. Fügen Sie den Code dann in CalculatorLibrary.cs in den Namespace CalculatorLibrary ein.

    Fügen Sie außerdem public vor Calculator-Klasse ein, um sie außerhalb der Bibliothek zur Verfügung zu stellen.

    CalculatorLibrary.cs sollte nun dem folgenden Code ähneln:

    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 verfügt auch über einen Verweis, aber ein Fehler besagt, dass der Calculator.DoOperation-Aufruf nicht aufgelöst wird. Der Fehler liegt daran, dass sich CalculatorLibrary in einem anderen Namespace befindet. Für einen vollqualifizierten Verweis können Sie dem Calculator.DoOperation-Aufruf den Namespace CalculatorLibrary hinzufügen:

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

    Sie können auch versuchen, eine using-Anweisung am Anfang der Datei hinzuzufügen:

    using CalculatorLibrary;
    

    Durch das Hinzufügen der using-Anweisung sollten Sie dazu in der Lage sein, den CalculatorLibrary-Namespace aus der Aufrufsite zu entfernen, jedoch liegt nun eine Mehrdeutigkeit vor. Ist Calculator die Klasse in CalculatorLibrary, oder ist Calculator der Namespace?

    Um die Mehrdeutigkeit zu beheben, benennen Sie den Namespace in program.cs von Calculator in CalculatorProgram um.

    namespace CalculatorProgram
    
  1. Klicken Sie im Projektmappen-Explorermit der rechten Maustaste auf den Projektmappenknoten, und wählen Sie Hinzufügen>Neues Projekt.

  2. Geben Sie auf im Fenster Neues Projekt hinzufügenclass library (Klassenbibliothek) in das Suchfeld ein. Wählen Sie die C#-Projektvorlage Klassenbibliothek und dann Weiter aus.

    Screenshot of Class Library project template selection.

  3. Geben Sie im Dialogfeld Neues Projekt konfigurieren den Projektnamen CalculatorLibrary ein, und klicken Sie dann auf Weiter.

  4. Auf dem Bildschirm Zusätzliche Informationen ist .NET 8.0 ausgewählt. Klicken Sie auf Erstellen.

    Visual Studio erstellt das neue Projekt und fügt es zur Projektmappe hinzu.

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

  5. Benennen Sie die Datei Class1.cs in CalculatorLibrary.cs um. Um die Datei umzubenennen, können Sie im Projektmappen-Explorer mit der rechten Maustaste auf den Namen klicken und Umbenennen auswählen, den Namen auswählen und F2 drücken, oder den Namen auswählen und erneut auswählen, um die Eingabe zu ermöglichen.

    In einer Meldung wird möglicherweise gefragt, ob Sie alle Verweise auf Class1 in der Datei umbenennen möchten. Es spielt keine Rolle, wie Sie antworten, da Sie den Code in einem zukünftigen Schritt ersetzen.

  6. Fügen Sie jetzt einen Projektverweis hinzu, damit das erste Projekt die APIs nutzen kann, die von der neuen Klassenbibliothek zur Verfügung gestellt werden. Klicken Sie mit der rechten Maustaste im ersten Projekt auf den Knoten Abhängigkeiten im Calculator-Projekt, und wählen Sie dann Projektverweis hinzufügen aus.

    Screenshot of the Add Project Reference menu item.

    Das Dialogfeld Verweis-Manager wird angezeigt. In diesem Dialogfeld können Sie Verweise auf andere Projekte sowie Assemblys und COM-DLLs hinzufügen, die Ihre Projekte benötigen.

  7. Aktivieren Sie im Dialogfeld Verweis-Manager das Kontrollkästchen für das Projekt CalculatorLibrary, und klicken Sie dann auf OK.

    Screenshot of the Reference Manager dialog box.

    Der Projektverweis wird unter dem Knoten Projekte im Projektmappen-Explorer angezeigt.

    Screenshot of Solution Explorer with project reference.

  8. Wählen Sie in der Datei Program.cs die Klasse Calculator und ihren gesamten Code aus, und drücken Sie STRG+X, um alles auszuschneiden. Fügen Sie den Code dann in CalculatorLibrary.cs in den Namespace CalculatorLibrary ein.

    Fügen Sie außerdem public vor Calculator-Klasse ein, um sie außerhalb der Bibliothek zur Verfügung zu stellen.

    CalculatorLibrary.cs sollte nun dem folgenden Code ähneln:

     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 verfügt auch über einen Verweis, aber ein Fehler besagt, dass der Calculator.DoOperation-Aufruf nicht aufgelöst wird. Der Fehler liegt daran, dass sich CalculatorLibrary in einem anderen Namespace befindet. Für einen vollqualifizierten Verweis können Sie dem Calculator.DoOperation-Aufruf den Namespace CalculatorLibrary hinzufügen:

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

    Sie können auch versuchen, eine using-Anweisung am Anfang der Datei hinzuzufügen:

    using CalculatorLibrary;
    

    Durch das Hinzufügen der using-Anweisung sollten Sie dazu in der Lage sein, den CalculatorLibrary-Namespace aus der Aufrufsite zu entfernen, jedoch liegt nun eine Mehrdeutigkeit vor. Ist Calculator die Klasse in CalculatorLibrary, oder ist Calculator der Namespace?

    Um die Mehrdeutigkeit zu beheben, benennen Sie den Namespace in program.cs von Calculator in CalculatorProgram um.

    namespace CalculatorProgram
    

Referenzieren von .NET-Bibliotheken: Schreiben in ein Protokoll

Sie können die .NET-Klasse Trace verwenden, um ein Protokoll aller Vorgänge hinzuzufügen und in eine Textdatei zu schreiben. Die Trace-Klasse ist auch für grundlegende Ausgabedebugverfahren nützlich. Die Trace-Klasse befindet sich in System.Diagnostics und verwendet System.IO-Klassen wie StreamWriter.

  1. Fügen Sie zunächst die using-Direktiven am Anfang von CalculatorLibrary.cs hinzu:

    using System.IO;
    using System.Diagnostics;
    
  2. Diese Verwendung der Trace-Klasse muss einen Verweis für die Klasse enthalten, die sie einem Filestream zu ordnet. Diese Anforderung bedeutet, der Rechner als Objekt besser funktioniert. Fügen Sie daher am Anfang der Calculator-Klasse in CalculatorLibrary.cs einen Konstruktor hinzu.

    Entfernen Sie auch das static-Schlüsselwort, um die statische DoOperation-Methode in eine Membermethode zu ändern.

    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. Fügen Sie jeder Berechnung eine Protokollausgabe hinzu. DoOperation sollte nun wie der folgende Code aussehen:

    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. Zurück in Program.cs kennzeichnet nun eine rote Schlangenlinie den statischen Aufruf. Erstellen Sie eine calculator-Variable, indem Sie die folgende Codezeile unmittelbar vor der while (!endApp)-Schleife hinzufügen, um den Fehler zu beheben:

    Calculator calculator = new Calculator();
    

    Ändern Sie außerdem die DoOperation-Aufrufsite so, dass sie auf das Objekt namens calculator (in Kleinbuchstaben) verweist. Der Code ist jetzt ein Memberaufruf und kein Aufruf einer statischen Methode.

    result = calculator.DoOperation(cleanNum1, cleanNum2, op);
    
  5. Führen Sie die App erneut aus. Wenn Sie fertig sind, klicken Sie mit der rechten Maustaste auf den Projektknoten Calculator, und wählen Sie Ordner im Datei-Explorer öffnen aus.

  6. Navigieren Sie im Datei-Explorer zum Ausgabeordner unter bin/Debug/ , und öffnen Sie die Datei calculator.log. Die Ausgabe sollte ungefähr wie folgt aussehen:

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

Zu diesem Zeitpunkt sollte die Datei CalculatorLibrary.cs dem folgenden Code ähneln:

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 sollte dem folgenden Code ähneln:

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

Sie können die .NET-Klasse Trace verwenden, um ein Protokoll aller Vorgänge hinzuzufügen und in eine Textdatei zu schreiben. Die Trace-Klasse ist auch für grundlegende Ausgabedebugverfahren nützlich. Die Trace-Klasse befindet sich in System.Diagnostics und verwendet System.IO-Klassen wie StreamWriter.

  1. Fügen Sie zunächst die using-Direktiven am Anfang von CalculatorLibrary.cs hinzu:

    using System.Diagnostics;
    
  2. Diese Verwendung der Trace-Klasse muss einen Verweis für die Klasse enthalten, die sie einem Filestream zu ordnet. Diese Anforderung bedeutet, der Rechner als Objekt besser funktioniert. Fügen Sie daher am Anfang der Calculator-Klasse in CalculatorLibrary.cs einen Konstruktor hinzu.

    Entfernen Sie auch das static-Schlüsselwort, um die statische DoOperation-Methode in eine Membermethode zu ändern.

    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. Fügen Sie jeder Berechnung eine Protokollausgabe hinzu. DoOperation sollte nun wie der folgende Code aussehen:

    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. Zurück in Program.cs kennzeichnet nun eine rote Schlangenlinie den statischen Aufruf. Erstellen Sie eine calculator-Variable, indem Sie die folgende Codezeile unmittelbar vor der while (!endApp)-Schleife hinzufügen, um den Fehler zu beheben:

    Calculator calculator = new Calculator();
    

    Ändern Sie außerdem die DoOperation-Aufrufsite so, dass sie auf das Objekt namens calculator (in Kleinbuchstaben) verweist. Der Code ist jetzt ein Memberaufruf und kein Aufruf einer statischen Methode.

    result = calculator.DoOperation(cleanNum1, cleanNum2, op);
    
  5. Führen Sie die App erneut aus. Wenn Sie fertig sind, klicken Sie mit der rechten Maustaste auf den Projektknoten Calculator, und wählen Sie Ordner im Datei-Explorer öffnen aus.

  6. Navigieren Sie im Datei-Explorer zum Ausgabeordner unter bin/Debug/ , und öffnen Sie die Datei calculator.log. Die Ausgabe sollte ungefähr wie folgt aussehen:

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

Zu diesem Zeitpunkt sollte die Datei CalculatorLibrary.cs dem folgenden Code ähneln:

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 sollte dem folgenden Code ähneln:

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

Hinzufügen eines NuGet-Pakets: Schreiben in eine JSON-Datei

Um Vorgänge in JSON auszugeben, einem beliebten und portierbaren Format zum Speichern von Objektdaten, können Sie auf das NuGet-Paket Newtonsoft.Json verweisen. NuGet-Pakete sind die primäre Verteilungsmethode für .NET-Klassenbibliotheken.

  1. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste für das Projekt CalculatorLibrary auf den Knoten Abhängigkeiten, und wählen Sie dann NuGet-Pakete verwalten aus.

    Screenshot of Manage NuGet Packages on the shortcut menu.

    Screenshot of Manage NuGet Packages on the shortcut menu.

    Daraufhin wird der NuGet-Paket-Manager geöffnet.

    Screenshot of the NuGet Package Manager.

  2. Suchen Sie nach dem Paket Newtonsoft.Json, wählen Sie es aus, und wählen Sie dann Installieren aus.

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

    Visual Studio lädt das Paket herunter und fügt es dem Projekt hinzu. Ein neuer Eintrag wird im Knoten „Verweise“ im Projektmappen-Explorer angezeigt.

    Screenshot of Newtonsoft J SON NuGet package information in the NuGet Package Manager. Wenn Sie gefragt werden, ob Sie die Änderungen akzeptieren möchten, wählen Sie OK aus.

    Visual Studio lädt das Paket herunter und fügt es dem Projekt hinzu. Ein neuer Eintrag wird in einem Knoten Pakete im Projektmappen-Explorer angezeigt.

    Fügen Sie eine using-Anweisung für Newtonsoft.Json am Anfang von CalculatorLibrary.cs hinzu.

    using Newtonsoft.Json;
    
  3. Erstellen Sie das JsonWriter-Memberobjekt, und ersetzen Sie den Calculator-Konstruktor durch den folgenden Code:

         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. Ändern Sie die DoOperation-Methode, um den JSON-writer-Code hinzuzufügen:

         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. Fügen Sie eine Methode hinzu, um die JSON-Syntax zu beenden, sobald der Benutzer damit fertig ist, Vorgangsdaten einzugeben.

     public void Finish()
     {
         writer.WriteEndArray();
         writer.WriteEndObject();
         writer.Close();
     }
    
  6. Fügen Sie am Ende von Program.cs vor return; einen Aufruf von Finish hinzu:

             // Add call to close the JSON writer before return
             calculator.Finish();
             return;
         }
    
  7. Erstellen Sie die App, und führen Sie sie aus. Nachdem Sie einige Vorgänge eingegeben haben, schließen Sie die App, indem Sie den Befehl n eingeben.

  8. Öffnen Sie die Datei calculatorlog.json im Datei-Explorer. Es sollte ungefähr der folgende Inhalt angezeigt werden:

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

Debuggen: Festlegen und Erreichen eines Breakpoint

Der Visual Studio-Debugger ist ein praktisches Tool. Der Debugger kann Ihren Code schrittweise durchlaufen, um den genauen Punkt zu ermitteln, an dem ein Programmierfehler auftritt. Sie können dann verstehen, welche Korrekturen Sie vornehmen müssen, und vorübergehende Änderungen anbringen, damit Sie Ihre App weiter ausführen können.

  1. Klicken Sie in Program.cs auf den Zwischenraum links neben der folgenden Codezeile. Sie können auch in der Zeile klicken und F9 auswählen oder mit der rechten Maustaste auf die Zeile klicken und Breakpoint>Breakpoint einfügen auswählen.

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

    Der angezeigte rote Punkt weist auf einen Breakpoint hin. Mithilfe von Haltepunkten können Sie Ihre App anhalten und den Code untersuchen. Sie können einen Haltepunkt für jede beliebige Zeile mit ausführbarem Code festlegen.

    Screenshot that shows setting a breakpoint.

  2. Erstellen Sie die App, und führen Sie sie aus. Geben Sie die folgende Werte für die Berechnung ein:

    • Geben Sie als erste Zahl 8 ein.
    • Geben Sie als zweite Zahl 0 ein.
    • Spielen wir ein wenig mit dem Operator. Geben Sie d ein.

    Die App pausiert an der Position des Haltepunkts, dies ist am links angezeigten gelben Pfeil und am hervorgehobenen Code erkennbar. Der hervorgehobene Code wurde noch nicht ausgeführt.

    Screenshot of hitting a breakpoint

    Da die App nun angehalten wurde, können Sie den Zustand Ihrer Anwendung untersuchen.

Debuggen: Anzeigen von Variablen

  1. Bewegen Sie im hervorgehobenen Code den Mauszeiger über Variablen wie z. B. cleanNum1 und op. Die aktuellen Werte für diese Variablen (8 bzw. d) werden in DataTips angezeigt.

    Screenshot that shows viewing a DataTip.

    Bei der Fehlersuche ist die Überprüfung, ob Variablen die erwarteten Werte enthalten, oft entscheidend für die Korrektur von Problemen.

  2. Sehen Sie sich im unteren Bereich das Fenster Lokal an. Wählen Sie Debuggen>Fenster>Lokal aus, falls es nicht geöffnet ist.

    Im Fenster Lokal werden alle Variablen angezeigt, die sich derzeit im Bereich befinden, gemeinsam mit dem zugehörigen Wert und Typ.

    Screenshot of the Locals window.

    Screenshot of the Locals window.

  3. Sehen Sie sich das Fenster Auto an.

    Das Fenster „Auto“ ähnelt dem Fenster Lokal, zeigt jedoch die Variablen direkt vor und nach der aktuellen Codezeile, an der Ihre App angehalten wurde.

    Hinweis

    Wenn das Fenster „Autos“ nicht angezeigt wird, wählen Sie Debuggen>Fenster>Autos aus, um es zu öffnen.

Nun führen Sie den Code im Debugger Anweisung für Anweisung aus. Dieses Vorgehen wird als Einzelschrittausführung bezeichnet.

Debuggen: Schritt-für-Schritt-Ausführung des Codes

  1. Drücken Sie F11, oder wählen Sie Debuggen>Einzelschritt aus.

    Bei Verwendung des Befehls „Einzelschritt“ führt die App die aktuelle Anweisung aus und wechselt zur nächsten ausführbaren Anweisung. Dies ist üblicherweise die nächste Codezeile. Der gelbe Pfeil auf der linken Seiten verweist jeweils auf die aktuelle Anweisung.

    Screenshot of step into command

    Sie haben soeben einen Einzelschritt in die Methode DoOperation der Klasse Calculator ausgeführt.

  2. Betrachten Sie das Fenster Aufrufliste, um eine hierarchische Ansicht des Programmflows zu erhalten. Wählen Sie Debuggen>Fenster>Aufrufliste aus, falls es nicht geöffnet ist.

    Screenshot of the call stack

    In dieser Ansicht wird die aktuelle Calculator.DoOperation-Methode angezeigt, die durch den gelben Pfeil angegeben wird. Die zweite Zeile zeigt die Funktion, die die Methode aus der Main-Methode in Program.cs aufgerufen hat.

    Im Fenster Aufrufliste wird die Reihenfolge angezeigt, in der Methoden und Funktionen aufgerufen werden. Dieses Fenster bietet auch über das Kontextmenü Zugriff auf zahlreiche Debuggerfeatures, darunter beispielsweise Zum Quellcode wechseln.

  3. Drücken Sie wiederholt F10, oder wählen Sie Debuggen>Prozedurschritt aus, bis die App an der Anweisung switch angehalten wird.

    switch (op)
    {
    

    Der Befehl „Prozedurschritt“ ähnelt dem Befehl „Einzelschritt“, weist aber folgenden Unterschied auf: Wenn die aktuelle Anweisung eine Funktion aufruft, führt der Debugger den Code in der Funktion auf und hält die Ausführung erst an, wenn die Funktion zurückgegeben wird. Mit dem Befehl „Prozedurschritt“ kann der Code schneller als mit „Einzelschritt“ durchlaufen werden, wenn Sie an einer bestimmten Funktion nicht interessiert sind.

  4. Drücken Sie nochmals F10, damit die App an der folgenden Codezeile angehalten wird.

    if (num2 != 0)
    {
    

    Dieser Code überprüft, ob eine Division durch 0 durchgeführt wird. Wenn die App fortgesetzt wird, wird eine allgemeine Ausnahme (ein Fehler) ausgelöst, aber Sie können auch etwas anderes versuchen, z. B. den tatsächlich zurückgegebenen Wert in der Konsole anzeigen. Eine Option besteht darin, das Debuggerfeature namens Bearbeiten und fortfahren zu verwenden, um Änderungen am Code vorzunehmen und das Debuggen fortzusetzen. Es gibt aber noch einen anderen Trick, um den Ausführungsflow vorübergehend zu ändern.

Debuggen: Testen einer vorübergehenden Änderung

  1. Wählen Sie den gelben Pfeil aus, der im angehaltenen Zustand aktuell auf die Anweisung if (num2 != 0) zeigt, und ziehen Sie ihn auf die folgende Anweisung:

    result = num1 / num2;
    

    Durch das Ziehen des Pfeils auf diese Anweisung überspringt die App die Anweisung if vollständig, sodass Sie sehen können, was bei einer Division durch 0 geschieht.

  2. Drücken Sie F10, um die Codezeile auszuführen.

  3. Wenn Sie mit dem Mauszeiger auf die result-Variable zeigen, wird der Wert Unendlich angezeigt. In C# ist „Unendlich“ das Ergebnis einer Division durch 0.

  4. Drücken Sie F5, oder wählen Sie Debuggen>Debuggen fortsetzen aus.

    Das Unendlichkeitssymbol wird in der Konsole als Ergebnis der mathematischen Operation angezeigt.

  5. Schließen Sie die App ordnungsgemäß, indem Sie den Befehl n eingeben.

Vollständiger Code

Dies ist der vollständige Code für die Datei CalculatorLibrary.cs, nachdem Sie alle Schritte ausgeführt haben:

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

Der Code für die Datei Program.cs sieht folgendermaßen aus:

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

Dies ist der vollständige Code für die Datei CalculatorLibrary.cs, nachdem Sie alle Schritte ausgeführt haben:

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

Der Code für die Datei Program.cs sieht folgendermaßen aus:

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

Nächste Schritte

Damit haben Sie das Tutorial erfolgreich abgeschlossen. Weitere Informationen finden Sie in den folgenden Inhalten: