Tutoriel : Étendre l’application console C# et déboguer dans Visual Studio (partie 2 sur 2)
Dans la deuxième partie de cette série de tutoriels, vous allez explorer un peu plus en détail les fonctionnalités de génération et de débogage de Visual Studio dont vous avez besoin pour le développement quotidien. Ces fonctionnalités incluent la gestion des projets multiples, le débogage et le référencement de packages tiers. Vous exécutez l’application console C# que vous avez créée dans la partie 1 de ce tutoriel et explorez certaines fonctionnalités de l’environnement de développement intégré (IDE) Visual Studio. Ce tutoriel est le deuxième d’une série de deux.
Dans ce tutoriel, vous allez effectuer les tâches suivantes :
- Ajoutez un deuxième projet.
- Référencez des bibliothèques et ajoutez des packages.
- Déboguez votre code.
- Inspectez votre code terminé.
Prérequis
Pour parcourir cet article, vous pouvez utiliser l’une des applications de calculatrice suivantes :
- L’application console calculatrice de la partie 1 de ce tutoriel.
- Application calculatrice C# dans le référentiel vs-tutorial-samples. Pour commencer, ouvrez l’application à partir du référentiel.
Ajouter un autre projet
Le code réel implique des projets fonctionnant ensemble dans une solution. Vous pouvez ajouter un projet de bibliothèque de classes à votre application de calculatrice qui fournit certaines fonctions de calculatrice.
Dans Visual Studio, vous utilisez la commande de menu Fichier>Ajouter>Nouveau projet pour ajouter un nouveau projet. Vous pouvez également cliquer avec le bouton droit sur la solution dans l’Explorateur de solutions pour ajouter un projet à partir du menu contextuel.
Dans l’Explorateur de solutions, cliquez avec le bouton droit sur le nœud de la solution et choisissez Ajouter>Nouveau projet.
Dans la fenêtre Ajouter un nouveau projet, tapez bibliothèque de classes dans la zone de recherche. Choisissez le modèle de projet Bibliothèque de classes C#, puis sélectionnez Suivant.
Dans l’écran Configurer votre nouveau projet, tapez le nom de projet CalculatorLibrary, puis sélectionnez Suivant.
Choisissez .NET 3.1 lorsque vous y êtes invité. Visual Studio crée le projet et l’ajoute à la solution.
Renommez le fichier Class1.cs en CalculatorLibrary.cs. Pour renommer le fichier, vous pouvez cliquer avec le bouton droit sur le nom dans l’Explorateur de solutions et choisir Renommer, sélectionner le nom et appuyer sur F2, ou sélectionner le nom et cliquer à nouveau pour taper.
Un message peut vous demander si vous souhaitez renommer les références à
Class1
dans le fichier. La façon dont vous répondez n’a pas d’importance, car vous remplacerez le code dans une étape ultérieure.Ajoutez maintenant une référence de projet afin que le premier projet puisse utiliser les API exposées par la nouvelle bibliothèque de classes. Cliquez avec le bouton droit sur le nœud Dépendances dans le projet Calculatrice et choisissez Ajouter une référence de projet.
La boîte de dialogue Gestionnaire de références s’affiche. Dans cette boîte de dialogue, vous pouvez ajouter des références à d’autres projets, assemblys et DLL COM dont vos projets ont besoin.
Dans la boîte de dialogue Gestionnaire de références, cochez la case du projet CalculatorLibrary, puis sélectionnez OK.
La référence de projet apparaît sous un nœud Projets dans l’Explorateur de solutions.
Dans Program.cs, sélectionnez la classe
Calculator
et tout son code, puis appuyez sur Ctrl+X pour la couper. Ensuite, dans CalculatorLibrary.cs, collez le code dans l’espace de nomsCalculatorLibrary
.Ajoutez également
public
avant la classe Calculator pour l’exposer en dehors de la bibliothèque.CalculatorLibrary.cs devrait maintenant ressembler au code suivant :
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 contient également une référence, mais une erreur indique que l’appel
Calculator.DoOperation
n’est pas résolu. L’erreur est due au fait queCalculatorLibrary
se trouve dans un espace de noms différent. Pour une référence complète, vous pouvez ajouter l’espace de nomsCalculatorLibrary
à l’appelCalculator.DoOperation
:result = CalculatorLibrary.Calculator.DoOperation(cleanNum1, cleanNum2, op);
Vous pouvez également essayer d’ajouter une directive
using
au début du fichier :using CalculatorLibrary;
L’ajout de la directive
using
devrait vous permettre de supprimer l’espace de nomsCalculatorLibrary
du site d’appel, mais il existe maintenant une ambiguïté. La classeCalculator
est-elle dansCalculatorLibrary
, ou est-ce queCalculator
est l’espace de noms ?Pour résoudre l’ambiguïté, renommez l’espace de noms
Calculator
enCalculatorProgram
dans Program.cs.namespace CalculatorProgram
Dans l’Explorateur de solutions, cliquez avec le bouton droit sur le nœud de la solution et choisissez Ajouter>Nouveau projet.
Dans la fenêtre Ajouter un nouveau projet, tapez bibliothèque de classes dans la zone de recherche. Choisissez le modèle de projet Bibliothèque de classes C#, puis sélectionnez Suivant.
Dans l’écran Configurer votre nouveau projet, tapez le nom de projet CalculatorLibrary, puis sélectionnez Suivant.
Dans l’écran Informations supplémentaires, .NET 8.0 est sélectionné. Sélectionnez Créer.
Visual Studio crée le projet et l’ajoute à la solution.
Renommez le fichier Class1.cs en CalculatorLibrary.cs. Pour renommer le fichier, vous pouvez cliquer avec le bouton droit sur le nom dans l’Explorateur de solutions et choisir Renommer, sélectionner le nom et appuyer sur F2, ou sélectionner le nom et cliquer à nouveau pour taper.
Un message peut vous demander si vous souhaitez renommer toutes les références à
Class1
dans le fichier. La façon dont vous répondez n’a pas d’importance, car vous remplacerez le code dans une étape ultérieure.Ajoutez maintenant une référence de projet afin que le premier projet puisse utiliser les API exposées par la nouvelle bibliothèque de classes. Cliquez avec le bouton droit sur le nœud Dépendances dans le projet Calculatrice et choisissez Ajouter une référence de projet.
La boîte de dialogue Gestionnaire de références s’affiche. Dans cette boîte de dialogue, vous pouvez ajouter des références à d’autres projets, assemblys et DLL COM dont vos projets ont besoin.
Dans la boîte de dialogue Gestionnaire de références, cochez la case du projet CalculatorLibrary, puis sélectionnez OK.
La référence de projet apparaît sous un nœud Projets dans l’Explorateur de solutions.
Dans Program.cs, sélectionnez la classe
Calculator
et tout son code, puis appuyez sur Ctrl+X pour la couper. Ensuite, dans CalculatorLibrary.cs, collez le code dans l’espace de nomsCalculatorLibrary
.Ajoutez également
public
avant la classe Calculator pour l’exposer en dehors de la bibliothèque.CalculatorLibrary.cs devrait maintenant ressembler au code suivant :
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 contient également une référence, mais une erreur indique que l’appel
Calculator.DoOperation
n’est pas résolu. L’erreur est due au fait queCalculatorLibrary
se trouve dans un espace de noms différent. Pour une référence complète, vous pouvez ajouter l’espace de nomsCalculatorLibrary
à l’appelCalculator.DoOperation
:result = CalculatorLibrary.Calculator.DoOperation(cleanNum1, cleanNum2, op);
Vous pouvez également essayer d’ajouter une directive
using
au début du fichier :using CalculatorLibrary;
L’ajout de la directive
using
devrait vous permettre de supprimer l’espace de nomsCalculatorLibrary
du site d’appel, mais il existe maintenant une ambiguïté. La classeCalculator
est-elle dansCalculatorLibrary
, ou est-ce queCalculator
est l’espace de noms ?Pour résoudre l’ambiguïté, renommez l’espace de noms
Calculator
enCalculatorProgram
dans Program.cs.namespace CalculatorProgram
Référencer les bibliothèques .NET : écrire dans un journal
Vous pouvez utiliser la classe .NET Trace pour ajouter un journal de toutes les opérations et l’écrire dans un fichier texte. La classe Trace
est également utile pour les techniques de débogage d’impression de base. La classe Trace
se trouve dans System.Diagnostics
et utilise des classes System.IO
comme StreamWriter
.
Commencez par ajouter les directives
using
en haut de CalculatorLibrary.cs :using System.IO; using System.Diagnostics;
Cette utilisation de la classe
Trace
doit contenir une référence pour la classe, qu’elle associe à un flux de fichiers. Cette exigence signifie que la calculatrice fonctionne mieux en tant qu’objet, aussi ajoutez un constructeur au début de la classeCalculator
dans CalculatorLibrary.cs.Supprimez également le mot clé
static
pour modifier la méthodeDoOperation
statique en méthode membre.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) {
Ajoutez la sortie du journal à chaque calcul.
DoOperation
doit maintenant ressembler au code suivant :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; }
Dans Program.cs, un trait de soulignement rouge marque maintenant l’appel statique. Pour corriger l’erreur, créez une variable
calculator
en ajoutant la ligne de code suivante juste avant la bouclewhile (!endApp)
:Calculator calculator = new Calculator();
Modifiez également le site d’appel
DoOperation
pour référencer l’objet nommécalculator
en minuscules. Le code est désormais un appel de membre, plutôt qu’un appel à une méthode statique.result = calculator.DoOperation(cleanNum1, cleanNum2, op);
Réexécutez l’application. Lorsque vous avez terminé, cliquez avec le bouton droit sur le nœud du projet Calculatrice et choisissez Ouvrir le dossier dans l’Explorateur de fichiers.
Dans l’Explorateur de fichiers, accédez au dossier de sortie sous bin/Debug/, puis ouvrez le fichier calculator.log. Le résultat suivant doit ressembler à ce qui suit :
Starting Calculator Log Started 7/9/2020 1:58:19 PM 1 + 2 = 3 3 * 3 = 9
À ce stade, CalculatorLibrary.cs devrait ressembler à ce code :
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 devrait ressembler au code suivant :
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;
}
}
}
Vous pouvez utiliser la classe .NET Trace pour ajouter un journal de toutes les opérations et l’écrire dans un fichier texte. La classe Trace
est également utile pour les techniques de débogage d’impression de base. La classe Trace
se trouve dans System.Diagnostics
et utilise des classes System.IO
comme StreamWriter
.
Commencez par ajouter les directives
using
en haut de CalculatorLibrary.cs :using System.Diagnostics;
Cette utilisation de la classe
Trace
doit contenir une référence pour la classe, qu’elle associe à un flux de fichiers. Cette exigence signifie que la calculatrice fonctionne mieux en tant qu’objet, aussi ajoutez un constructeur au début de la classeCalculator
dans CalculatorLibrary.cs.Supprimez également le mot clé
static
pour modifier la méthodeDoOperation
statique en méthode membre.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) {
Ajoutez la sortie du journal à chaque calcul.
DoOperation
doit maintenant ressembler au code suivant :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; }
Dans Program.cs, un trait de soulignement rouge marque maintenant l’appel statique. Pour corriger l’erreur, créez une variable
calculator
en ajoutant la ligne de code suivante juste avant la bouclewhile (!endApp)
:Calculator calculator = new Calculator();
Modifiez également le site d’appel
DoOperation
pour référencer l’objet nommécalculator
en minuscules. Le code est désormais un appel de membre, plutôt qu’un appel à une méthode statique.result = calculator.DoOperation(cleanNum1, cleanNum2, op);
Réexécutez l’application. Lorsque vous avez terminé, cliquez avec le bouton droit sur le nœud du projet Calculatrice et choisissez Ouvrir le dossier dans l’Explorateur de fichiers.
Dans l’Explorateur de fichiers, accédez au dossier de sortie sous bin/Debug/, puis ouvrez le fichier calculator.log. Le résultat suivant doit ressembler à ce qui suit :
Starting Calculator Log Started 7/9/2020 1:58:19 PM 1 + 2 = 3 3 * 3 = 9
À ce stade, CalculatorLibrary.cs devrait ressembler à ce code :
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 devrait ressembler au code suivant :
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;
}
}
}
Ajouter un package NuGet : écrire dans un fichier JSON
Pour générer des opérations en JSON, un format populaire et portable pour le stockage des données d’objet, vous pouvez référencer le package NuGet Newtonsoft.Json. Les packages NuGet sont la méthode de distribution principale pour les bibliothèques de classes .NET.
Dans l’Explorateur de solutions, cliquez avec le bouton droit sur le nœud Dépendances du projet CalculatorLibrary, puis choisissez Gérer les packages NuGet.
Le Gestionnaire de package NuGet s’ouvre.
Recherchez et sélectionnez le package Newtonsoft.Json, puis sélectionnez Installer.
Visual Studio télécharge le package et l’ajoute au projet. Une nouvelle entrée apparaît dans le nœud Références dans l’Explorateur de solutions.
Si vous êtes invité à accepter les modifications, sélectionnez OK.
Visual Studio télécharge le package et l’ajoute au projet. Une nouvelle entrée apparaît dans un nœud Packages dans l’Explorateur de solutions.
Ajoutez une directive
using
pourNewtonsoft.Json
au début de CalculatorLibrary.cs.using Newtonsoft.Json;
Créez l’objet membre
JsonWriter
et remplacez le constructeurCalculator
par le code suivant :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(); }
Modifiez la méthode
DoOperation
pour ajouter le code 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; }
Ajoutez une méthode pour terminer la syntaxe JSON une fois que l’utilisateur a fini de saisir les données d’opération.
public void Finish() { writer.WriteEndArray(); writer.WriteEndObject(); writer.Close(); }
À la fin de Program.cs, avant le
return;
, ajoutez un appel àFinish
:// Add call to close the JSON writer before return calculator.Finish(); return; }
Générez et exécutez l’application et, une fois que vous avez terminé d’entrer quelques opérations, fermez l’application en entrant la commande n.
Ouvrez le fichier calculatorlog.json dans l’Explorateur de fichiers. Vous devriez voir quelque chose qui ressemble à ce qui suit :
{ "Operations": [ { "Operand1": 2.0, "Operand2": 3.0, "Operation": "Add", "Result": 5.0 }, { "Operand1": 3.0, "Operand2": 4.0, "Operation": "Multiply", "Result": 12.0 } ] }
Débogage : Définir et atteindre un point d’arrêt
Le débogueur Visual Studio est un outil puissant. Le débogueur peut parcourir votre code pour trouver le point exact où il y a une erreur de programmation. Vous pouvez ensuite comprendre les corrections que vous devez apporter et effectuer des modifications temporaires afin de continuer à exécuter votre application.
Dans Program.cs, cliquez dans la marge à gauche de la ligne de code suivante. Vous pouvez également cliquer sur la ligne et sélectionner F9, ou cliquer avec le bouton droit sur la ligne, puis sélectionner Point d’arrêt>Insérer un point d’arrêt.
result = calculator.DoOperation(cleanNum1, cleanNum2, op);
Le point rouge qui s’affiche indique un point d’arrêt. Vous pouvez utiliser des points d’arrêt pour suspendre votre application et inspecter le code. Vous pouvez définir un point d’arrêt sur n’importe quelle ligne de code exécutable.
Générez et exécutez l'application. Entrez les valeurs suivantes pour le calcul :
- Pour le premier nombre, entrez 8.
- Pour le deuxième, entrez 0.
- Pour l’opérateur, amusons-nous un peu. Entrez d.
L’application suspend l’endroit où vous avez créé le point d’arrêt, indiqué par le pointeur jaune à gauche et le code mis en surbrillance. Le code mis en surbrillance n’a pas encore été exécuté.
Maintenant, une fois l’application suspendue, vous pouvez inspecter l’état de votre application.
Débogage : Afficher les variables
Dans le code mis en surbrillance, pointez sur des variables comme
cleanNum1
etop
. Les valeurs actuelles de ces variables,8
etd
respectivement, s’affichent dans DataTips.Lors du débogage, il est souvent essentiel de vérifier si les variables contiennent les valeurs attendues pour résoudre les problèmes.
Dans le volet inférieur, regardez la fenêtre Variables locales. S’il est fermé, sélectionnez Débogage>Fenêtres>Variables locales pour l’ouvrir.
La fenêtre Variables locales affiche chaque variable actuellement dans l’étendue, ainsi que sa valeur et son type.
Regardez la fenêtre Autos.
La fenêtre Autos est similaire à la fenêtre Variables locales, mais affiche les variables qui précèdent et suivent immédiatement la ligne de code actuelle où votre application est suspendue.
Note
Si la fenêtre Autos ne s’affiche pas, sélectionnez Déboguer>Windows>Autos pour l’ouvrir.
Ensuite, exécutez du code dans le débogueur une instruction à la fois ; c’est ce qu’on appelle le pas à pas.
Débogage : Pas à pas détaillé du code
Appuyez sur F11 ou sélectionnez Débogage>Pas à pas.
À l’aide de la commande Pas à pas détaillé, l’application exécute l’instruction actuelle et passe à l’instruction exécutable suivante, généralement la ligne de code suivante. Le pointeur jaune à gauche indique toujours l’instruction actuelle.
Vous venez d’entrer dans la méthode
DoOperation
dans la classeCalculator
.Pour obtenir un aperçu hiérarchique de votre flux de programme, observez la fenêtre Pile des appels. Si elle est fermée, sélectionnez Débogage>Fenêtres>Pile des appels pour l’ouvrir.
Cette vue montre la méthode
Calculator.DoOperation
actuelle, indiquée par le pointeur jaune. La deuxième ligne montre la fonction qui a appelé la méthode, à partir de la méthodeMain
dans Program.cs.La fenêtre Pile des appels montre l’ordre dans lequel les méthodes et les fonctions sont appelées. Cette fenêtre permet également d’accéder à de nombreuses fonctionnalités du débogueur, comme Accéder au code source, à partir de son menu contextuel.
Appuyez sur F10 ou sélectionnez Débogage>Pas à pas jusqu’à ce que l’application s’arrête sur l’instruction
switch
.switch (op) {
La commande Pas à pas principal est similaire à la commande Pas à pas détaillé, sauf que si l’instruction actuelle appelle une fonction, le débogueur exécute le code dans la fonction et n’interrompt pas l’exécution tant que la fonction n’est pas retournée. Pas à pas principal est plus rapide que Pas à pas détaillé si vous n’êtes pas intéressé par une fonction particulière.
Appuyez une fois de plus sur F10 pour que l’application s’interrompe sur la ligne de code suivante.
if (num2 != 0) {
Ce code recherche un cas de division par zéro. Si l’application continue, elle lève une exception générale (une erreur), mais vous pouvez essayer autre chose, comme afficher la valeur réelle retournée dans la console. Une option consiste à utiliser une fonctionnalité de débogueur appelée Modifier et Continuer pour apporter des modifications au code, puis poursuivre le débogage. Toutefois, il existe une autre astuce pour modifier temporairement le flux d’exécution.
Débogage : Tester une modification temporaire
Sélectionnez le pointeur jaune, actuellement suspendu sur l’instruction
if (num2 != 0)
, puis faites-le glisser vers l’instruction suivante :result = num1 / num2;
Si vous faites glisser le pointeur ici, l’application ignore complètement l’instruction
if
, ce qui vous permet de voir ce qui se passe lorsque vous divisez par zéro.Appuyez sur F10 pour exécuter la ligne de code.
Si vous pointez sur la variable
result
, elle affiche la valeur Infini. En C#, Infini est le résultat lorsque vous divisez par zéro.Appuyez sur F5 ou sélectionnez Déboguer>Continuer le débogage.
Le symbole infini apparaît dans la console en tant que résultat de l’opération mathématique.
Fermez l’application correctement en entrant la commande n.
Code terminé
Voici le code complet du fichier CalculatorLibrary.cs, après avoir effectué toutes les étapes :
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();
}
}
}
Et voici le code pour 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;
}
}
}
Voici le code complet du fichier CalculatorLibrary.cs, après avoir effectué toutes les étapes :
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();
}
}
}
Et voici le code pour 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;
}
}
}
Étapes suivantes
Félicitations ! Vous avez terminé ce didacticiel. Pour en savoir plus, passez au contenu suivant :
- Continuer avec d’autres tutoriels C#
- Démarrage rapide : créer une application web ASP .NET Core
- Apprendre à déboguer du code C# dans Visual Studio
- Guide pratique pour créer et exécuter des tests unitaires
- Exécuter un programme C#
- En savoir plus sur IntelliSense C#
- Continuer avec la vue d’ensemble de l’IDE Visual Studio
- Journalisation et suivi