Esercitazione: Estendere l'app console C# ed eseguire il debug in Visual Studio (parte 2 di 2)
Nella parte 2 di questa serie di esercitazioni si approfondirà le funzionalità di compilazione e debug di Visual Studio necessarie per lo sviluppo giornaliero. Queste funzionalità includono la gestione di più progetti, debug e riferimento a pacchetti di terze parti. Eseguire l'app console C# creata nella parte 1 di questa esercitazione ed esplorare alcune funzionalità dell'ambiente di sviluppo integrato (IDE) di Visual Studio. Questa esercitazione è la parte 2 di una serie di esercitazioni in due parti.
In questa esercitazione si completano le attività seguenti:
- Aggiungere un secondo progetto.
- Librerie di riferimento e aggiungere pacchetti.
- Eseguire il debug del codice.
- Esaminare il codice completato.
Prerequisiti
Per eseguire questo articolo, è possibile usare una di queste app calcolatrice:
- App console calcolatrice della parte 1 di questa esercitazione.
- L'app calcolatrice C# nel repository vs-tutorial-samples. Per iniziare, aprire l'app dal repository.
Aggiungere un altro progetto
Il codice reale prevede progetti che interagiscono tra loro in una soluzione. È possibile aggiungere un progetto di libreria di classi all'app calcolatrice che fornisce alcune funzioni di calcolatrice.
In Visual Studio si usa il comando di menu File>Aggiungi>nuovo progetto per aggiungere un nuovo progetto. È anche possibile fare clic con il pulsante destro del mouse sulla soluzione in Esplora soluzioni per aggiungere un progetto dal menu di scelta rapida.
In Esplora soluzioni fare clic con il pulsante destro del mouse sul nodo della soluzione e scegliere Aggiungi>nuovo progetto.
Nella finestra Aggiungi un nuovo progetto digitare libreria di classi nella casella Di ricerca. Scegliere il modello di progetto libreria di classi C# e quindi selezionare Avanti.
Nella schermata Configura il nuovo progetto digitare il nome del progetto CalculatorLibrary e quindi selezionare Avanti.
Scegliere .NET 3.1 quando richiesto. Visual Studio crea il nuovo progetto e lo aggiunge alla soluzione.
Rinominare il file Class1.cs in CalculatorLibrary.cs. Per rinominare il file, è possibile fare clic con il pulsante destro del mouse sul nome in Esplora soluzioni e scegliere Rinomina, selezionare il nome e premere F2 oppure selezionare di nuovo il nome e selezionare di nuovo per digitare.
Un messaggio potrebbe chiedere se si desidera rinominare i riferimenti in
Class1
nel file. Non importa come rispondere, perché il codice verrà sostituito in un passaggio futuro.Aggiungere ora un riferimento al progetto, in modo che il primo progetto possa usare le API esposte dalla nuova libreria di classi. Fare clic con il pulsante destro del mouse sul nodo Dipendenze nel progetto Calculator e scegliere Aggiungi riferimento progetto.
Verrà visualizzata la finestra di dialogo Gestione riferimenti. In questa finestra di dialogo è possibile aggiungere riferimenti ad altri progetti, assembly e DLL COM necessari per i progetti.
Nella finestra di dialogo Gestione riferimenti selezionare la casella di controllo per il progetto CalculatorLibrary e quindi selezionare OK.
Il riferimento al progetto viene visualizzato sotto un nodo Progetti in Esplora soluzioni.
In Program.cs selezionare la classe e tutto il
Calculator
codice e premere CTRL+X per tagliarla. Quindi, in CalculatorLibrary.cs incollare il codice nello spazio deiCalculatorLibrary
nomi .Aggiungere
public
anche prima della classe Calculator per esporla all'esterno della libreria.CalculatorLibrary.cs dovrebbe ora essere simile al codice seguente:
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 ha anche un riferimento, ma un errore indica che la
Calculator.DoOperation
chiamata non viene risolta. L'errore è dovuto al fatto cheCalculatorLibrary
si trova in uno spazio dei nomi diverso. Per un riferimento completo, è possibile aggiungere loCalculatorLibrary
spazio dei nomi allaCalculator.DoOperation
chiamata:result = CalculatorLibrary.Calculator.DoOperation(cleanNum1, cleanNum2, op);
In alternativa, è possibile provare ad aggiungere una
using
direttiva all'inizio del file:using CalculatorLibrary;
L'aggiunta della
using
direttiva dovrebbe consentire di rimuovere loCalculatorLibrary
spazio dei nomi dal sito di chiamata, ma ora c'è un'ambiguità. La classe èCalculator
inCalculatorLibrary
o èCalculator
lo spazio dei nomi ?Per risolvere l'ambiguità, rinominare lo spazio dei nomi da
Calculator
aCalculatorProgram
in Program.cs.namespace CalculatorProgram
In Esplora soluzioni fare clic con il pulsante destro del mouse sul nodo della soluzione e scegliere Aggiungi>nuovo progetto.
Nella finestra Aggiungi un nuovo progetto digitare libreria di classi nella casella Di ricerca. Scegliere il modello di progetto libreria di classi C# e quindi selezionare Avanti.
Nella schermata Configura il nuovo progetto digitare il nome del progetto CalculatorLibrary e quindi selezionare Avanti.
Nella schermata Informazioni aggiuntive è selezionata l'opzione .NET 8.0. Seleziona Crea.
Visual Studio crea il nuovo progetto e lo aggiunge alla soluzione.
Rinominare il file Class1.cs in CalculatorLibrary.cs. Per rinominare il file, è possibile fare clic con il pulsante destro del mouse sul nome in Esplora soluzioni e scegliere Rinomina, selezionare il nome e premere F2 oppure selezionare di nuovo il nome e selezionare di nuovo per digitare.
Un messaggio potrebbe chiedere se si desidera rinominare tutti i riferimenti in
Class1
nel file. Non importa come rispondere, perché il codice verrà sostituito in un passaggio futuro.Aggiungere ora un riferimento al progetto, in modo che il primo progetto possa usare le API esposte dalla nuova libreria di classi. Fare clic con il pulsante destro del mouse sul nodo Dipendenze nel progetto Calculator e scegliere Aggiungi riferimento progetto.
Verrà visualizzata la finestra di dialogo Gestione riferimenti. In questa finestra di dialogo è possibile aggiungere riferimenti ad altri progetti, assembly e DLL COM necessari per i progetti.
Nella finestra di dialogo Gestione riferimenti selezionare la casella di controllo per il progetto CalculatorLibrary e quindi selezionare OK.
Il riferimento al progetto viene visualizzato sotto un nodo Progetti in Esplora soluzioni.
In Program.cs selezionare la classe e tutto il
Calculator
codice e premere CTRL+X per tagliarla. Quindi, in CalculatorLibrary.cs incollare il codice nello spazio deiCalculatorLibrary
nomi .Aggiungere
public
anche prima della classe Calculator per esporla all'esterno della libreria.CalculatorLibrary.cs dovrebbe ora essere simile al codice seguente:
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 ha anche un riferimento, ma un errore indica che la
Calculator.DoOperation
chiamata non viene risolta. L'errore è dovuto al fatto cheCalculatorLibrary
si trova in uno spazio dei nomi diverso. Per un riferimento completo, è possibile aggiungere loCalculatorLibrary
spazio dei nomi allaCalculator.DoOperation
chiamata:result = CalculatorLibrary.Calculator.DoOperation(cleanNum1, cleanNum2, op);
In alternativa, è possibile provare ad aggiungere una
using
direttiva all'inizio del file:using CalculatorLibrary;
L'aggiunta della
using
direttiva dovrebbe consentire di rimuovere loCalculatorLibrary
spazio dei nomi dal sito di chiamata, ma ora c'è un'ambiguità. La classe èCalculator
inCalculatorLibrary
o èCalculator
lo spazio dei nomi ?Per risolvere l'ambiguità, rinominare lo spazio dei nomi da
Calculator
aCalculatorProgram
in Program.cs.namespace CalculatorProgram
Fare riferimento alle librerie .NET: Scrivere in un log
È possibile usare la classe Trace .NET per aggiungere un log di tutte le operazioni e scriverlo in un file di testo. La Trace
classe è utile anche per le tecniche di debug di stampa di base. La Trace
classe è in System.Diagnostics
e usa System.IO
classi come StreamWriter
.
Per iniziare, aggiungere le
using
direttive nella parte superiore di CalculatorLibrary.cs:using System.IO; using System.Diagnostics;
Questo utilizzo della
Trace
classe deve contenere un riferimento per la classe associata a un filestream. Questo requisito indica che la calcolatrice funziona meglio come oggetto, quindi aggiungere un costruttore all'inizio dellaCalculator
classe in CalculatorLibrary.cs.Rimuovere anche la
static
parola chiave per modificare il metodo staticoDoOperation
in un metodo membro.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) {
Aggiungere l'output del log a ogni calcolo.
DoOperation
dovrebbe ora essere simile al codice seguente: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; }
Tornare a Program.cs, una sottolineatura ondulata rossa contrassegna ora la chiamata statica. Per correggere l'errore, creare una
calculator
variabile aggiungendo la riga di codice seguente subito prima delwhile (!endApp)
ciclo:Calculator calculator = new Calculator();
Modificare anche il
DoOperation
sito di chiamata per fare riferimento all'oggetto denominatocalculator
in lettere minuscole. Il codice è ora una chiamata membro, anziché una chiamata a un metodo statico.result = calculator.DoOperation(cleanNum1, cleanNum2, op);
Eseguire nuovamente l'app. Al termine, fare clic con il pulsante destro del mouse sul nodo del progetto Calculator e scegliere Apri cartella in Esplora file.
In Esplora file passare alla cartella di output in bin/Debug/e aprire il file calculator.log. L'output dovrebbe essere simile al seguente:
Starting Calculator Log Started 7/9/2020 1:58:19 PM 1 + 2 = 3 3 * 3 = 9
A questo punto, CalculatorLibrary.cs dovrebbe essere simile al codice seguente:
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 dovrebbe essere simile al codice seguente:
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;
}
}
}
È possibile usare la classe Trace .NET per aggiungere un log di tutte le operazioni e scriverlo in un file di testo. La Trace
classe è utile anche per le tecniche di debug di stampa di base. La Trace
classe è in System.Diagnostics
e usa System.IO
classi come StreamWriter
.
Per iniziare, aggiungere le
using
direttive nella parte superiore di CalculatorLibrary.cs:using System.Diagnostics;
Questo utilizzo della
Trace
classe deve contenere un riferimento per la classe associata a un filestream. Questo requisito indica che la calcolatrice funziona meglio come oggetto, quindi aggiungere un costruttore all'inizio dellaCalculator
classe in CalculatorLibrary.cs.Rimuovere anche la
static
parola chiave per modificare il metodo staticoDoOperation
in un metodo membro.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) {
Aggiungere l'output del log a ogni calcolo.
DoOperation
dovrebbe ora essere simile al codice seguente: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; }
Tornare a Program.cs, una sottolineatura ondulata rossa contrassegna ora la chiamata statica. Per correggere l'errore, creare una
calculator
variabile aggiungendo la riga di codice seguente subito prima delwhile (!endApp)
ciclo:Calculator calculator = new Calculator();
Modificare anche il
DoOperation
sito di chiamata per fare riferimento all'oggetto denominatocalculator
in lettere minuscole. Il codice è ora una chiamata membro, anziché una chiamata a un metodo statico.result = calculator.DoOperation(cleanNum1, cleanNum2, op);
Eseguire nuovamente l'app. Al termine, fare clic con il pulsante destro del mouse sul nodo del progetto Calculator e scegliere Apri cartella in Esplora file.
In Esplora file passare alla cartella di output in bin/Debug/e aprire il file calculator.log. L'output dovrebbe essere simile al seguente:
Starting Calculator Log Started 7/9/2020 1:58:19 PM 1 + 2 = 3 3 * 3 = 9
A questo punto, CalculatorLibrary.cs dovrebbe essere simile al codice seguente:
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 dovrebbe essere simile al codice seguente:
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;
}
}
}
Aggiungere un pacchetto NuGet: scrivere in un file JSON
Per eseguire operazioni di output in JSON, un formato diffuso e portabile per l'archiviazione dei dati degli oggetti, è possibile fare riferimento al pacchetto NuGet Newtonsoft.Json . I pacchetti NuGet sono il metodo di distribuzione principale per le librerie di classi .NET.
In Esplora soluzioni fare clic con il pulsante destro del mouse sul nodo Dipendenze per il progetto CalculatorLibrary e scegliere Gestisci pacchetti NuGet.
Verrà aperto il Gestione pacchetti NuGet.
Cercare e selezionare il pacchetto Newtonsoft.Json e selezionare Installa.
Visual Studio scarica il pacchetto e lo aggiunge al progetto. Viene visualizzata una nuova voce nel nodo Riferimenti in Esplora soluzioni.
Se viene richiesto se accettare le modifiche, selezionare OK.
Visual Studio scarica il pacchetto e lo aggiunge al progetto. Una nuova voce viene visualizzata in un nodo Pacchetti in Esplora soluzioni.
Aggiungere una
using
direttiva perNewtonsoft.Json
all'inizio di CalculatorLibrary.cs.using Newtonsoft.Json;
Creare l'oggetto
JsonWriter
membro e sostituire ilCalculator
costruttore con il codice seguente: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(); }
Modificare il
DoOperation
metodo per aggiungere il codice JSONwriter
: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; }
Aggiungere un metodo per completare la sintassi JSON al termine dell'immissione dei dati dell'operazione da parte dell'utente.
public void Finish() { writer.WriteEndArray(); writer.WriteEndObject(); writer.Close(); }
Alla fine di Program.cs, prima di
return;
, aggiungere una chiamata aFinish
:// Add call to close the JSON writer before return calculator.Finish(); return; }
Compilare ed eseguire l'app e dopo aver completato l'immissione di alcune operazioni, chiudere l'app immettendo il comando n .
Aprire il file calculatorlog.json in Esplora file. Verrà visualizzato un contenuto simile al seguente:
{ "Operations": [ { "Operand1": 2.0, "Operand2": 3.0, "Operation": "Add", "Result": 5.0 }, { "Operand1": 3.0, "Operand2": 4.0, "Operation": "Multiply", "Result": 12.0 } ] }
Debug: impostare e raggiungere un punto di interruzione
Il debugger di Visual Studio è uno strumento potente. Il debugger può eseguire il codice per trovare il punto esatto in cui si verifica un errore di programmazione. È quindi possibile comprendere quali correzioni è necessario apportare e apportare modifiche temporanee in modo da poter continuare a eseguire l'app.
In Program.cs fare clic sulla barra a sinistra della riga di codice seguente. È anche possibile fare clic sulla riga e scegliere F9 oppure fare clic con il pulsante destro del mouse sulla riga e scegliere Inserisci punto> di interruzione.
result = calculator.DoOperation(cleanNum1, cleanNum2, op);
Il punto rosso visualizzato indica un punto di interruzione. Puoi usare i punti di interruzione per sospendere l'app ed esaminare il codice. È possibile impostare un punto di interruzione in qualsiasi riga di codice eseguibile.
Compilare ed eseguire l'app. Immettere i valori seguenti per il calcolo:
- Per il primo numero immettere 8.
- Per il secondo numero immettere 0.
- Per l'operatore, diamo un po' di divertimento. Immettere d.
L'app sospende dove è stato creato il punto di interruzione, indicato dal puntatore giallo a sinistra e dal codice evidenziato. Il codice evidenziato non è ancora stato eseguito.
Ora, con l'app sospesa, è possibile controllare lo stato dell'applicazione.
Debug: Visualizzare le variabili
Nel codice evidenziato passare il puntatore del mouse sulle variabili come
cleanNum1
eop
. I valori correnti per queste variabili8
ed
, rispettivamente, vengono visualizzati in Data Suggerimenti.Durante il debug, verificare se le variabili contengono i valori previsti è spesso fondamentale per risolvere i problemi.
Nel riquadro inferiore esaminare la finestra Variabili locali . Se è chiuso, selezionare Debug>variabili locali di Windows>per aprirlo.
La finestra Variabili locali mostra ogni variabile attualmente nell'ambito, insieme al relativo valore e tipo.
Esaminare la finestra Auto .
La finestra Auto è simile alla finestra Variabili locali , ma mostra le variabili immediatamente precedenti e dopo la riga di codice corrente in cui viene sospesa l'app.
Nota
Se la finestra Auto non viene visualizzata, selezionare Debug>auto di Windows>per aprirla.
Successivamente, eseguire il codice nel debugger un'istruzione alla volta, denominata istruzione.
Debug: Eseguire l'istruzione del codice
Premere F11 o selezionare Debug>Passaggio in.
Usando il comando Esegui istruzione istruzione, l'app esegue l'istruzione corrente e passa all'istruzione eseguibile successiva, in genere la riga di codice successiva. Il puntatore giallo a sinistra indica sempre l'istruzione corrente.
È stato appena inserito il
DoOperation
metodo nellaCalculator
classe .Per ottenere un'occhiata gerarchica al flusso del programma, esaminare la finestra Stack di chiamate. Se è chiuso, selezionare Debug>stack di chiamate di Windows>per aprirlo.
Questa visualizzazione mostra il metodo corrente
Calculator.DoOperation
, indicato dal puntatore giallo. La seconda riga mostra la funzione che ha chiamato il metodo , dalMain
metodo in Program.cs.La finestra Stack di chiamate visualizza l'ordine in cui vengono chiamati metodi e funzioni. Questa finestra consente anche l'accesso a molte funzionalità del debugger, ad esempio Vai al codice sorgente, dal menu di scelta rapida.
Premere F10 o selezionare Debug>Passaggio su più volte fino a quando l'app non viene sospesa nell'istruzione.
switch
switch (op) {
Il comando Step Over è simile al comando Step Into, ad eccezione del fatto che se l'istruzione corrente chiama una funzione, il debugger esegue il codice nella funzione e non sospende l'esecuzione fino a quando la funzione non viene restituita. Step Over è più veloce di Esegui istruzione in se non si è interessati a una funzione specifica.
Premere F10 ancora una volta, in modo che l'app venga sospesa nella riga di codice seguente.
if (num2 != 0) {
Questo codice verifica la presenza di un caso di divisione per zero. Se l'app continua, genera un'eccezione generale (un errore), ma potrebbe essere necessario provare qualcos'altro, ad esempio visualizzare il valore restituito effettivo nella console. Un'opzione consiste nell'usare una funzionalità del debugger denominata edit-and-continue per apportare modifiche al codice e quindi continuare il debug. Tuttavia, esiste un altro trucco per modificare temporaneamente il flusso di esecuzione.
Debug: Testare una modifica temporanea
Selezionare il puntatore giallo, attualmente sospeso nell'istruzione
if (num2 != 0)
e trascinarlo nell'istruzione seguente:result = num1 / num2;
Il trascinamento del puntatore qui fa sì che l'app ignori completamente l'istruzione
if
, in modo da vedere cosa accade quando si divide per zero.Premere F10 per eseguire la riga di codice.
Se si passa il puntatore del mouse sulla
result
variabile, viene visualizzato il valore Infinity. In C#, Infinity è il risultato quando si divide per zero.Premere F5 o selezionare Debug>continua debug.
Il simbolo infinito viene visualizzato nella console come risultato dell'operazione matematica.
Chiudere correttamente l'app immettendo il comando n .
Completamento del codice
Ecco il codice completo per il file CalculatorLibrary.cs , dopo aver completato tutti i passaggi:
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();
}
}
}
Ecco il codice per 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;
}
}
}
Ecco il codice completo per il file CalculatorLibrary.cs , dopo aver completato tutti i passaggi:
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();
}
}
}
Ecco il codice per Program.cs:
using CalculatorLibrary;
namespace CalculatorProgram
{
class Program
{
static void Main(string[] args)
{
bool endApp = false;
// Display title as the C# console calculator app.
Console.WriteLine("Console Calculator in C#\r");
Console.WriteLine("------------------------\n");
Calculator calculator = new Calculator();
while (!endApp)
{
// Declare variables and set to empty.
string numInput1 = "";
string numInput2 = "";
double result = 0;
// Ask the user to type the first number.
Console.Write("Type a number, and then press Enter: ");
numInput1 = Console.ReadLine();
double cleanNum1 = 0;
while (!double.TryParse(numInput1, out cleanNum1))
{
Console.Write("This is not valid input. Please enter an integer value: ");
numInput1 = Console.ReadLine();
}
// Ask the user to type the second number.
Console.Write("Type another number, and then press Enter: ");
numInput2 = Console.ReadLine();
double cleanNum2 = 0;
while (!double.TryParse(numInput2, out cleanNum2))
{
Console.Write("This is not valid input. Please enter an integer value: ");
numInput2 = Console.ReadLine();
}
// Ask the user to choose an operator.
Console.WriteLine("Choose an operator from the following list:");
Console.WriteLine("\ta - Add");
Console.WriteLine("\ts - Subtract");
Console.WriteLine("\tm - Multiply");
Console.WriteLine("\td - Divide");
Console.Write("Your option? ");
string op = Console.ReadLine();
try
{
result = calculator.DoOperation(cleanNum1, cleanNum2, op);
if (double.IsNaN(result))
{
Console.WriteLine("This operation will result in a mathematical error.\n");
}
else Console.WriteLine("Your result: {0:0.##}\n", result);
}
catch (Exception e)
{
Console.WriteLine("Oh no! An exception occurred trying to do the math.\n - Details: " + e.Message);
}
Console.WriteLine("------------------------\n");
// Wait for the user to respond before closing.
Console.Write("Press 'n' and Enter to close the app, or press any other key and Enter to continue: ");
if (Console.ReadLine() == "n") endApp = true;
Console.WriteLine("\n"); // Friendly linespacing.
}
calculator.Finish();
return;
}
}
}
Passaggi successivi
L'esercitazione è stata completata. Per altre informazioni, continuare con il contenuto seguente:
- Altre esercitazioni su C#
- Guida introduttiva: Creare un'app Web ASP.NET Core
- Informazioni sul debug del codice C# in Visual Studio
- Procedura dettagliata per creare ed eseguire unit test
- Eseguire un programma C#
- Informazioni su IntelliSense per C#
- Continuare con la panoramica dell'IDE di Visual Studio
- Registrazione e traccia