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:
- Die Rechner-Konsolen-App aus Teil 1 dieses Tutorials
- Die C#-Rechner-App im Repository vs-tutorial-samples. Öffnen Sie als ersten Schritt die App aus dem Repository.
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.
Klicken Sie im Projektmappen-Explorermit der rechten Maustaste auf den Projektmappenknoten, und wählen Sie Hinzufügen>Neues Projekt.
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.
Geben Sie im Dialogfeld Neues Projekt konfigurieren den Projektnamen CalculatorLibrary ein, und klicken Sie dann auf Weiter.
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.
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.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.
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.
Aktivieren Sie im Dialogfeld Verweis-Manager das Kontrollkästchen für das Projekt CalculatorLibrary, und klicken Sie dann auf OK.
Der Projektverweis wird unter dem Knoten Projekte im Projektmappen-Explorer angezeigt.
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 NamespaceCalculatorLibrary
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; } } }
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 sichCalculatorLibrary
in einem anderen Namespace befindet. Für einen vollqualifizierten Verweis können Sie demCalculator.DoOperation
-Aufruf den NamespaceCalculatorLibrary
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, denCalculatorLibrary
-Namespace aus der Aufrufsite zu entfernen, jedoch liegt nun eine Mehrdeutigkeit vor. IstCalculator
die Klasse inCalculatorLibrary
, oder istCalculator
der Namespace?Um die Mehrdeutigkeit zu beheben, benennen Sie den Namespace in program.cs von
Calculator
inCalculatorProgram
um.namespace CalculatorProgram
Klicken Sie im Projektmappen-Explorermit der rechten Maustaste auf den Projektmappenknoten, und wählen Sie Hinzufügen>Neues Projekt.
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.
Geben Sie im Dialogfeld Neues Projekt konfigurieren den Projektnamen CalculatorLibrary ein, und klicken Sie dann auf Weiter.
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.
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.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.
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.
Aktivieren Sie im Dialogfeld Verweis-Manager das Kontrollkästchen für das Projekt CalculatorLibrary, und klicken Sie dann auf OK.
Der Projektverweis wird unter dem Knoten Projekte im Projektmappen-Explorer angezeigt.
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 NamespaceCalculatorLibrary
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; } } }
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 sichCalculatorLibrary
in einem anderen Namespace befindet. Für einen vollqualifizierten Verweis können Sie demCalculator.DoOperation
-Aufruf den NamespaceCalculatorLibrary
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, denCalculatorLibrary
-Namespace aus der Aufrufsite zu entfernen, jedoch liegt nun eine Mehrdeutigkeit vor. IstCalculator
die Klasse inCalculatorLibrary
, oder istCalculator
der Namespace?Um die Mehrdeutigkeit zu beheben, benennen Sie den Namespace in program.cs von
Calculator
inCalculatorProgram
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
.
Fügen Sie zunächst die
using
-Direktiven am Anfang von CalculatorLibrary.cs hinzu:using System.IO; using System.Diagnostics;
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 derCalculator
-Klasse in CalculatorLibrary.cs einen Konstruktor hinzu.Entfernen Sie auch das
static
-Schlüsselwort, um die statischeDoOperation
-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) {
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; }
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 derwhile (!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 namenscalculator
(in Kleinbuchstaben) verweist. Der Code ist jetzt ein Memberaufruf und kein Aufruf einer statischen Methode.result = calculator.DoOperation(cleanNum1, cleanNum2, op);
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.
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
.
Fügen Sie zunächst die
using
-Direktiven am Anfang von CalculatorLibrary.cs hinzu:using System.Diagnostics;
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 derCalculator
-Klasse in CalculatorLibrary.cs einen Konstruktor hinzu.Entfernen Sie auch das
static
-Schlüsselwort, um die statischeDoOperation
-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) {
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; }
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 derwhile (!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 namenscalculator
(in Kleinbuchstaben) verweist. Der Code ist jetzt ein Memberaufruf und kein Aufruf einer statischen Methode.result = calculator.DoOperation(cleanNum1, cleanNum2, op);
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.
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.
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.
Daraufhin wird der NuGet-Paket-Manager geöffnet.
Suchen Sie nach dem Paket Newtonsoft.Json, wählen Sie es aus, und wählen Sie dann Installieren aus.
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.
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ürNewtonsoft.Json
am Anfang von CalculatorLibrary.cs hinzu.using Newtonsoft.Json;
Erstellen Sie das
JsonWriter
-Memberobjekt, und ersetzen Sie denCalculator
-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(); }
Ä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; }
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(); }
Fügen Sie am Ende von Program.cs vor
return;
einen Aufruf vonFinish
hinzu:// Add call to close the JSON writer before return calculator.Finish(); return; }
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.
Ö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.
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.
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.
Da die App nun angehalten wurde, können Sie den Zustand Ihrer Anwendung untersuchen.
Debuggen: Anzeigen von Variablen
Bewegen Sie im hervorgehobenen Code den Mauszeiger über Variablen wie z. B.
cleanNum1
undop
. Die aktuellen Werte für diese Variablen (8
bzw.d
) werden in DataTips angezeigt.Bei der Fehlersuche ist die Überprüfung, ob Variablen die erwarteten Werte enthalten, oft entscheidend für die Korrektur von Problemen.
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.
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
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.
Sie haben soeben einen Einzelschritt in die Methode
DoOperation
der KlasseCalculator
ausgeführt.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.
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 derMain
-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.
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.
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
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.Drücken Sie F10, um die Codezeile auszuführen.
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.Drücken Sie F5, oder wählen Sie Debuggen>Debuggen fortsetzen aus.
Das Unendlichkeitssymbol wird in der Konsole als Ergebnis der mathematischen Operation angezeigt.
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:
- C#-Tutorials
- Schnellstart: Erstellen einer ASP.NET Core-Web-App
- Tutorial: Debuggen von C#-Code mit Visual Studio
- Exemplarische Vorgehensweise zum Erstellen und Ausführen von Komponententests
- Vorgehensweise: Ausführen eines C#-Programms in Visual Studio
- Informationen zu C# IntelliSense.
- Übersicht über die Visual Studio-IDE
- Protokollierung und Ablaufverfolgung