Samouczek: rozszerzanie aplikacji konsolowej języka C# i debugowanie w programie Visual Studio (część 2 z 2)
W części 2 tej serii samouczków bardziej szczegółowo poznasz funkcje kompilacji i debugowania programu Visual Studio potrzebne do codziennego programowania. Te funkcje obejmują zarządzanie wieloma projektami, debugowaniem i odwoływaniem się do pakietów innych firm. Uruchom aplikację konsolową języka C# utworzoną w części 1 tego samouczka i zapoznasz się z niektórymi funkcjami zintegrowanego środowiska projektowego (IDE) programu Visual Studio. Ten samouczek jest częścią 2 dwuczęściowej serii samouczków.
W tym samouczku wykonasz następujące zadania:
- Dodaj drugi projekt.
- Biblioteki referencyjne i dodaj pakiety.
- Debugowanie kodu.
- Sprawdź ukończony kod.
Wymagania wstępne
Aby pracować z tym artykułem, możesz użyć jednej z następujących aplikacji kalkulatora:
- Aplikacja konsolowa kalkulatora z części 1 tego samouczka.
- Aplikacja kalkulatora języka C# w repozytorium vs-tutorial-samples. Aby rozpocząć, otwórz aplikację z repozytorium.
Dodawanie innego projektu
Rzeczywisty kod obejmuje projekty współpracujące ze sobą w rozwiązaniu. Projekt biblioteki klas można dodać do aplikacji kalkulatora, która udostępnia niektóre funkcje kalkulatora.
W programie Visual Studio użyj polecenia menu Plik>dodaj>nowy projekt, aby dodać nowy projekt. Możesz również kliknąć rozwiązanie prawym przyciskiem myszy w Eksplorator rozwiązań, aby dodać projekt z menu kontekstowego.
W Eksplorator rozwiązań kliknij prawym przyciskiem myszy węzeł rozwiązania i wybierz polecenie Dodaj>nowy projekt.
W oknie Dodawanie nowego projektu wpisz bibliotekę klas w polu Wyszukaj. Wybierz szablon projektu Biblioteka klas języka C#, a następnie wybierz przycisk Dalej.
Na ekranie Konfigurowanie nowego projektu wpisz nazwę projektu CalculatorLibrary, a następnie wybierz pozycję Dalej.
Wybierz platformę .NET 3.1 po wyświetleniu monitu. Program Visual Studio tworzy nowy projekt i dodaje go do rozwiązania.
Zmień nazwę pliku Class1.cs na CalculatorLibrary.cs. Aby zmienić nazwę pliku, możesz kliknąć prawym przyciskiem myszy nazwę w Eksplorator rozwiązań i wybrać polecenie Zmień nazwę, wybrać nazwę i nacisnąć klawisz F2 lub wybrać nazwę i wybrać ponownie, aby wpisać.
Komunikat może zapytać, czy chcesz zmienić nazwę odwołań na
Class1
w pliku. Nie ma znaczenia, jak odpowiadasz, ponieważ zastąpisz kod w przyszłym kroku.Teraz dodaj odwołanie do projektu, aby pierwszy projekt mógł używać interfejsów API udostępnianych przez nową bibliotekę klas. Kliknij prawym przyciskiem myszy węzeł Zależności w projekcie Kalkulator i wybierz polecenie Dodaj odwołanie do projektu.
Zostanie wyświetlone okno dialogowe Menedżer odwołań. W tym oknie dialogowym można dodawać odwołania do innych projektów, zestawów i bibliotek DLL com potrzebnych w projektach.
W oknie dialogowym Menedżer odwołań zaznacz pole wyboru projektu CalculatorLibrary, a następnie wybierz przycisk OK.
Odwołanie do projektu zostanie wyświetlone w węźle Projekty w Eksplorator rozwiązań.
W pliku Program.cs wybierz klasę
Calculator
i cały jego kod, a następnie naciśnij klawisze Ctrl+X, aby go wyciąć. Następnie w pliku CalculatorLibrary.cs wklej kod doCalculatorLibrary
przestrzeni nazw.public
Dodaj również przed klasą Calculator, aby uwidocznić ją poza biblioteką.Plik CalculatorLibrary.cs powinien teraz wyglądać podobnie do następującego kodu:
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; } } }
Plik Program.cs zawiera również odwołanie, ale błąd wskazuje, że wywołanie nie rozwiązuje problemu
Calculator.DoOperation
. Błąd jest spowodowany tym, żeCalculatorLibrary
znajduje się w innej przestrzeni nazw. W przypadku w pełni kwalifikowanego odwołania można dodaćCalculatorLibrary
przestrzeń nazw do wywołaniaCalculator.DoOperation
:result = CalculatorLibrary.Calculator.DoOperation(cleanNum1, cleanNum2, op);
Możesz też spróbować dodać dyrektywę
using
na początku pliku:using CalculatorLibrary;
using
Dodanie dyrektywy powinno umożliwić usunięcieCalculatorLibrary
przestrzeni nazw z witryny wywołania, ale teraz istnieje niejednoznaczność. CzyCalculator
klasa w elemecieCalculatorLibrary
, czy jestCalculator
przestrzenią nazw?Aby rozwiązać niejednoznaczność, zmień nazwę przestrzeni nazw z
Calculator
naCalculatorProgram
w pliku Program.cs.namespace CalculatorProgram
W Eksplorator rozwiązań kliknij prawym przyciskiem myszy węzeł rozwiązania i wybierz polecenie Dodaj>nowy projekt.
W oknie Dodawanie nowego projektu wpisz bibliotekę klas w polu Wyszukaj. Wybierz szablon projektu Biblioteka klas języka C#, a następnie wybierz przycisk Dalej.
Na ekranie Konfigurowanie nowego projektu wpisz nazwę projektu CalculatorLibrary, a następnie wybierz pozycję Dalej.
Na ekranie Dodatkowe informacje wybrano pozycję .NET 8.0. Wybierz pozycję Utwórz.
Program Visual Studio tworzy nowy projekt i dodaje go do rozwiązania.
Zmień nazwę pliku Class1.cs na CalculatorLibrary.cs. Aby zmienić nazwę pliku, możesz kliknąć prawym przyciskiem myszy nazwę w Eksplorator rozwiązań i wybrać polecenie Zmień nazwę, wybrać nazwę i nacisnąć klawisz F2 lub wybrać nazwę i wybrać ponownie, aby wpisać.
Komunikat może zapytać, czy chcesz zmienić nazwę wszystkich odwołań do
Class1
w pliku. Nie ma znaczenia, jak odpowiadasz, ponieważ zastąpisz kod w przyszłym kroku.Teraz dodaj odwołanie do projektu, aby pierwszy projekt mógł używać interfejsów API udostępnianych przez nową bibliotekę klas. Kliknij prawym przyciskiem myszy węzeł Zależności w projekcie Kalkulator i wybierz polecenie Dodaj odwołanie do projektu.
Zostanie wyświetlone okno dialogowe Menedżer odwołań. W tym oknie dialogowym można dodawać odwołania do innych projektów, zestawów i bibliotek DLL com potrzebnych w projektach.
W oknie dialogowym Menedżer odwołań zaznacz pole wyboru projektu CalculatorLibrary, a następnie wybierz przycisk OK.
Odwołanie do projektu zostanie wyświetlone w węźle Projekty w Eksplorator rozwiązań.
W pliku Program.cs wybierz klasę
Calculator
i cały jego kod, a następnie naciśnij klawisze Ctrl+X, aby go wyciąć. Następnie w pliku CalculatorLibrary.cs wklej kod doCalculatorLibrary
przestrzeni nazw.public
Dodaj również przed klasą Calculator, aby uwidocznić ją poza biblioteką.Plik CalculatorLibrary.cs powinien teraz wyglądać podobnie do następującego kodu:
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; } } }
Plik Program.cs zawiera również odwołanie, ale błąd wskazuje, że wywołanie nie rozwiązuje problemu
Calculator.DoOperation
. Błąd jest spowodowany tym, żeCalculatorLibrary
znajduje się w innej przestrzeni nazw. W przypadku w pełni kwalifikowanego odwołania można dodaćCalculatorLibrary
przestrzeń nazw do wywołaniaCalculator.DoOperation
:result = CalculatorLibrary.Calculator.DoOperation(cleanNum1, cleanNum2, op);
Możesz też spróbować dodać dyrektywę
using
na początku pliku:using CalculatorLibrary;
using
Dodanie dyrektywy powinno umożliwić usunięcieCalculatorLibrary
przestrzeni nazw z witryny wywołania, ale teraz istnieje niejednoznaczność. CzyCalculator
klasa w elemecieCalculatorLibrary
, czy jestCalculator
przestrzenią nazw?Aby rozwiązać niejednoznaczność, zmień nazwę przestrzeni nazw z
Calculator
naCalculatorProgram
w pliku Program.cs.namespace CalculatorProgram
Dokumentacja bibliotek platformy .NET: zapisywanie w dzienniku
Możesz użyć klasy .NET Trace , aby dodać dziennik wszystkich operacji i zapisać go w pliku tekstowym. Klasa jest również przydatna Trace
w przypadku podstawowych technik debugowania wydruku. Klasa Trace
jest w System.Diagnostics
klasie i używa System.IO
klas takich jak StreamWriter
.
Zacznij od dodania
using
dyrektyw w górnej części pliku CalculatorLibrary.cs:using System.IO; using System.Diagnostics;
To użycie
Trace
klasy musi zawierać odwołanie do klasy, którą kojarzy z strumieniem plików. To wymaganie oznacza, że kalkulator działa lepiej jako obiekt, dlatego dodaj konstruktor na początkuCalculator
klasy w pliku CalculatorLibrary.cs.Usuń również słowo kluczowe ,
static
aby zmienić metodę statycznąDoOperation
na metodę składową.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) {
Dodaj dane wyjściowe dziennika do każdego obliczenia.
DoOperation
powinien teraz wyglądać podobnie do następującego kodu: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; }
Po powrocie do pliku Program.cs czerwone podkreślenie zwija się teraz flaguje wywołanie statyczne. Aby naprawić błąd, utwórz zmienną
calculator
, dodając następujący wiersz kodu tuż przed pętląwhile (!endApp)
:Calculator calculator = new Calculator();
Zmodyfikuj również lokację wywołania,
DoOperation
aby odwoływać się do obiektu o nazwiecalculator
w małych literach. Kod jest teraz wywołaniem elementu członkowskiego, a nie wywołaniem metody statycznej.result = calculator.DoOperation(cleanNum1, cleanNum2, op);
Ponownie uruchom aplikację. Po zakończeniu kliknij prawym przyciskiem myszy węzeł projektu Kalkulator i wybierz polecenie Otwórz folder w Eksplorator plików.
W Eksplorator plików przejdź do folderu wyjściowego w obszarze bin/Debug/, a następnie otwórz plik calculator.log. Dane wyjściowe powinny wyglądać następująco:
Starting Calculator Log Started 7/9/2020 1:58:19 PM 1 + 2 = 3 3 * 3 = 9
W tym momencie plik CalculatorLibrary.cs powinien przypominać następujący kod:
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;
}
}
}
Plik Program.cs powinien wyglądać podobnie do następującego kodu:
using System;
using CalculatorLibrary;
namespace CalculatorProgram
{
class Program
{
static void Main(string[] args)
{
bool endApp = false;
// Display title as the C# console calculator app.
Console.WriteLine("Console Calculator in C#\r");
Console.WriteLine("------------------------\n");
Calculator calculator = new Calculator();
while (!endApp)
{
// Declare variables and set to empty.
string numInput1 = "";
string numInput2 = "";
double result = 0;
// Ask the user to type the first number.
Console.Write("Type a number, and then press Enter: ");
numInput1 = Console.ReadLine();
double cleanNum1 = 0;
while (!double.TryParse(numInput1, out cleanNum1))
{
Console.Write("This is not valid input. Please enter an integer value: ");
numInput1 = Console.ReadLine();
}
// Ask the user to type the second number.
Console.Write("Type another number, and then press Enter: ");
numInput2 = Console.ReadLine();
double cleanNum2 = 0;
while (!double.TryParse(numInput2, out cleanNum2))
{
Console.Write("This is not valid input. Please enter an integer value: ");
numInput2 = Console.ReadLine();
}
// Ask the user to choose an operator.
Console.WriteLine("Choose an operator from the following list:");
Console.WriteLine("\ta - Add");
Console.WriteLine("\ts - Subtract");
Console.WriteLine("\tm - Multiply");
Console.WriteLine("\td - Divide");
Console.Write("Your option? ");
string op = Console.ReadLine();
try
{
result = calculator.DoOperation(cleanNum1, cleanNum2, op);
if (double.IsNaN(result))
{
Console.WriteLine("This operation will result in a mathematical error.\n");
}
else Console.WriteLine("Your result: {0:0.##}\n", result);
}
catch (Exception e)
{
Console.WriteLine("Oh no! An exception occurred trying to do the math.\n - Details: " + e.Message);
}
Console.WriteLine("------------------------\n");
// Wait for the user to respond before closing.
Console.Write("Press 'n' and Enter to close the app, or press any other key and Enter to continue: ");
if (Console.ReadLine() == "n") endApp = true;
Console.WriteLine("\n"); // Friendly linespacing.
}
return;
}
}
}
Możesz użyć klasy .NET Trace , aby dodać dziennik wszystkich operacji i zapisać go w pliku tekstowym. Klasa jest również przydatna Trace
w przypadku podstawowych technik debugowania wydruku. Klasa Trace
jest w System.Diagnostics
klasie i używa System.IO
klas takich jak StreamWriter
.
Zacznij od dodania
using
dyrektyw w górnej części pliku CalculatorLibrary.cs:using System.Diagnostics;
To użycie
Trace
klasy musi zawierać odwołanie do klasy, którą kojarzy z strumieniem plików. To wymaganie oznacza, że kalkulator działa lepiej jako obiekt, dlatego dodaj konstruktor na początkuCalculator
klasy w pliku CalculatorLibrary.cs.Usuń również słowo kluczowe ,
static
aby zmienić metodę statycznąDoOperation
na metodę składową.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) {
Dodaj dane wyjściowe dziennika do każdego obliczenia.
DoOperation
powinien teraz wyglądać podobnie do następującego kodu: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; }
Po powrocie do pliku Program.cs czerwone podkreślenie zwija się teraz flaguje wywołanie statyczne. Aby naprawić błąd, utwórz zmienną
calculator
, dodając następujący wiersz kodu tuż przed pętląwhile (!endApp)
:Calculator calculator = new Calculator();
Zmodyfikuj również lokację wywołania,
DoOperation
aby odwoływać się do obiektu o nazwiecalculator
w małych literach. Kod jest teraz wywołaniem elementu członkowskiego, a nie wywołaniem metody statycznej.result = calculator.DoOperation(cleanNum1, cleanNum2, op);
Ponownie uruchom aplikację. Po zakończeniu kliknij prawym przyciskiem myszy węzeł projektu Kalkulator i wybierz polecenie Otwórz folder w Eksplorator plików.
W Eksplorator plików przejdź do folderu wyjściowego w obszarze bin/Debug/, a następnie otwórz plik calculator.log. Dane wyjściowe powinny wyglądać następująco:
Starting Calculator Log Started 7/9/2020 1:58:19 PM 1 + 2 = 3 3 * 3 = 9
W tym momencie plik CalculatorLibrary.cs powinien przypominać następujący kod:
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;
}
}
}
Plik Program.cs powinien wyglądać podobnie do następującego kodu:
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;
}
}
}
Dodawanie pakietu NuGet: zapisywanie w pliku JSON
Aby wykonać operacje wyjściowe w formacie JSON, popularnym i przenośnym formacie do przechowywania danych obiektów, możesz odwołać się do pakietu NuGet Newtonsoft.Json . Pakiety NuGet to podstawowa metoda dystrybucji bibliotek klas platformy .NET.
W Eksplorator rozwiązań kliknij prawym przyciskiem myszy węzeł Zależności dla projektu CalculatorLibrary i wybierz pozycję Zarządzaj pakietami NuGet.
Zostanie otwarty Menedżer pakietów NuGet.
Wyszukaj i wybierz pakiet Newtonsoft.Json , a następnie wybierz pozycję Zainstaluj.
Program Visual Studio pobiera pakiet i dodaje go do projektu. Nowy wpis zostanie wyświetlony w węźle Odwołania w Eksplorator rozwiązań.
Jeśli zostanie wyświetlony monit o zaakceptowanie zmian, wybierz przycisk OK.
Program Visual Studio pobiera pakiet i dodaje go do projektu. Nowy wpis zostanie wyświetlony w węźle Pakiety w Eksplorator rozwiązań.
Dodaj dyrektywę
using
naNewtonsoft.Json
początku pliku CalculatorLibrary.cs.using Newtonsoft.Json;
JsonWriter
Utwórz obiekt członkowski i zastąpCalculator
konstruktor następującym kodem: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(); }
Zmodyfikuj metodę ,
DoOperation
aby dodać kod 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; }
Dodaj metodę, aby zakończyć składnię JSON po zakończeniu wprowadzania danych operacji przez użytkownika.
public void Finish() { writer.WriteEndArray(); writer.WriteEndObject(); writer.Close(); }
Na końcu pliku Program.cs dodaj
return;
wywołanie doFinish
pliku :// Add call to close the JSON writer before return calculator.Finish(); return; }
Skompiluj i uruchom aplikację, a po zakończeniu wprowadzania kilku operacji zamknij aplikację, wprowadzając n polecenia.
Otwórz plik calculatorlog.json w Eksplorator plików. Powinna zostać wyświetlona zawartość podobna do następującej:
{ "Operations": [ { "Operand1": 2.0, "Operand2": 3.0, "Operation": "Add", "Result": 5.0 }, { "Operand1": 3.0, "Operand2": 4.0, "Operation": "Multiply", "Result": 12.0 } ] }
Debugowanie: ustawianie i trafienie punktu przerwania
Debuger programu Visual Studio to zaawansowane narzędzie. Debuger może przejść przez kod, aby znaleźć dokładny punkt, w którym wystąpił błąd programowania. Następnie możesz zrozumieć, jakie poprawki należy wprowadzić, i wprowadzić tymczasowe zmiany, aby móc kontynuować uruchamianie aplikacji.
W pliku Program.cs kliknij w rynnie po lewej stronie następującego wiersza kodu. Możesz również kliknąć wiersz i wybrać klawisz F9 lub kliknąć wiersz prawym przyciskiem myszy i wybrać pozycję Punkt przerwania Wstaw punkt> przerwania.
result = calculator.DoOperation(cleanNum1, cleanNum2, op);
Zostanie wyświetlona czerwona kropka wskazująca punkt przerwania. Możesz użyć punktów przerwania, aby wstrzymać aplikację i sprawdzić kod. Punkt przerwania można ustawić na dowolnym wykonywalnym wierszu kodu.
Skompiluj i uruchom aplikację. Wprowadź następujące wartości dla obliczenia:
- Dla pierwszej liczby wprowadź wartość 8.
- W przypadku drugiej liczby wprowadź wartość 0.
- Dla operatora bawmy się dobrze. Wprowadź d.
Aplikacja zawiesza się w miejscu utworzenia punktu przerwania, który jest wskazywany przez żółty wskaźnik po lewej stronie i wyróżniony kod. Wyróżniony kod nie został jeszcze wykonany.
Teraz po wstrzymaniu aplikacji możesz sprawdzić stan aplikacji.
Debugowanie: Wyświetlanie zmiennych
W wyróżnionym kodzie umieść kursor na zmiennych, takich jak
cleanNum1
iop
. Bieżące wartości tych zmiennych8
id
odpowiednio są wyświetlane w obszarze Dane Wskazówki.Podczas debugowania sprawdź, czy zmienne przechowują oczekiwane wartości, często ma kluczowe znaczenie dla rozwiązywania problemów.
W dolnym okienku przyjrzyj się oknie Ustawienia lokalne . Jeśli jest zamknięta, wybierz pozycję Debuguj>ustawienia lokalne systemu Windows>, aby go otworzyć.
W oknie Ustawienia lokalne jest wyświetlana każda zmienna, która jest obecnie w zakresie, wraz z jego wartością i typem.
Spójrz na okno Autos (Autos ).
Okno Autos jest podobne do okna Ustawienia lokalne , ale pokazuje zmienne bezpośrednio poprzedzające i postępując zgodnie z bieżącym wierszem kodu, w którym aplikacja jest wstrzymana.
Uwaga
Jeśli nie widzisz okna Automatyczne, wybierz pozycję Debuguj>autos windows>, aby go otworzyć.
Następnie wykonaj kod w jednej instrukcji debugera, która jest nazywana krokiem.
Debugowanie: przechodzenie przez kod
Naciśnij klawisz F11 lub wybierz pozycję Debuguj>krok do.
Za pomocą polecenia Krok do aplikacja wykonuje bieżącą instrukcję i przechodzi do następnej instrukcji wykonywalnej, zwykle w następnym wierszu kodu. Żółty wskaźnik po lewej stronie zawsze wskazuje bieżącą instrukcję.
Właśnie wszedłeś do
DoOperation
metody wCalculator
klasie .Aby uzyskać hierarchiczny wygląd przepływu programu, zapoznaj się z oknem stosu wywołań . Jeśli jest zamknięty, wybierz pozycję Debuguj>stos wywołań systemu Windows>, aby go otworzyć.
Ten widok przedstawia bieżącą
Calculator.DoOperation
metodę wskazywaną przez żółty wskaźnik. Drugi wiersz przedstawia funkcję, która nazwała metodę , zMain
metody w pliku Program.cs.W oknie Stos wywołań jest wyświetlana kolejność wywoływania metod i funkcji. To okno zapewnia również dostęp do wielu funkcji debugera, takich jak Przejdź do kodu źródłowego, z menu skrótów.
Naciśnij klawisz F10 lub wybierz pozycję Debuguj>krok po kroku, kilka razy, aż aplikacja zostanie wstrzymana w instrukcji .
switch
switch (op) {
Polecenie Step Over jest podobne do polecenia Step Into, z tą różnicą, że jeśli bieżąca instrukcja wywołuje funkcję, debuger uruchamia kod w funkcji i nie zawiesza wykonywania, dopóki funkcja nie powróci. Krok do kroku jest szybszy niż Krok do, jeśli nie interesuje Cię określona funkcja.
Naciśnij klawisz F10 jeszcze raz, aby aplikacja wstrzymała się w następującym wierszu kodu.
if (num2 != 0) {
Ten kod sprawdza wielkość liter z podziałem przez zero. Jeśli aplikacja będzie nadal występować, zgłasza ogólny wyjątek (błąd), ale możesz spróbować wykonać inne czynności, na przykład wyświetlenie rzeczywistej zwróconej wartości w konsoli programu . Jedną z opcji jest użycie funkcji debugera o nazwie edit-and-continue , aby wprowadzić zmiany w kodzie, a następnie kontynuować debugowanie. Istnieje jednak inna sztuczka, aby tymczasowo zmodyfikować przepływ wykonywania.
Debugowanie: testowanie tymczasowej zmiany
Wybierz żółty wskaźnik, obecnie wstrzymany w instrukcji
if (num2 != 0)
i przeciągnij go do następującej instrukcji:result = num1 / num2;
Przeciągnięcie wskaźnika powoduje całkowite pominięcie
if
instrukcji przez aplikację, dzięki czemu możesz zobaczyć, co się stanie po podzieleniu przez zero.Naciśnij klawisz F10 , aby wykonać wiersz kodu.
Po umieszczeniu wskaźnika myszy na zmiennej
result
zostanie wyświetlona wartość Nieskończoność. W języku C# nieskończoność jest wynikiem dzielenia przez zero.Naciśnij klawisz F5 lub wybierz pozycję Debuguj>kontynuuj debugowanie.
Symbol nieskończoności pojawia się w konsoli w wyniku operacji matematycznej.
Zamknij aplikację prawidłowo, wprowadzając n polecenia.
Ukończono kod
Oto kompletny kod pliku CalculatorLibrary.cs po wykonaniu wszystkich kroków:
using System;
using System.IO;
using Newtonsoft.Json;
namespace CalculatorLibrary
{
public class Calculator
{
JsonWriter writer;
public Calculator()
{
StreamWriter logFile = File.CreateText("calculatorlog.json");
logFile.AutoFlush = true;
writer = new JsonTextWriter(logFile);
writer.Formatting = Formatting.Indented;
writer.WriteStartObject();
writer.WritePropertyName("Operations");
writer.WriteStartArray();
}
public double DoOperation(double num1, double num2, string op)
{
double result = double.NaN; // Default value is "not-a-number" if an operation, such as division, could result in an error.
writer.WriteStartObject();
writer.WritePropertyName("Operand1");
writer.WriteValue(num1);
writer.WritePropertyName("Operand2");
writer.WriteValue(num2);
writer.WritePropertyName("Operation");
// Use a switch statement to do the math.
switch (op)
{
case "a":
result = num1 + num2;
writer.WriteValue("Add");
break;
case "s":
result = num1 - num2;
writer.WriteValue("Subtract");
break;
case "m":
result = num1 * num2;
writer.WriteValue("Multiply");
break;
case "d":
// Ask the user to enter a non-zero divisor.
if (num2 != 0)
{
result = num1 / num2;
}
writer.WriteValue("Divide");
break;
// Return text for an incorrect option entry.
default:
break;
}
writer.WritePropertyName("Result");
writer.WriteValue(result);
writer.WriteEndObject();
return result;
}
public void Finish()
{
writer.WriteEndArray();
writer.WriteEndObject();
writer.Close();
}
}
}
Oto kod pliku Program.cs:
using System;
using CalculatorLibrary;
namespace CalculatorProgram
{
class Program
{
static void Main(string[] args)
{
bool endApp = false;
// Display title as the C# console calculator app.
Console.WriteLine("Console Calculator in C#\r");
Console.WriteLine("------------------------\n");
Calculator calculator = new Calculator();
while (!endApp)
{
// Declare variables and set to empty.
string numInput1 = "";
string numInput2 = "";
double result = 0;
// Ask the user to type the first number.
Console.Write("Type a number, and then press Enter: ");
numInput1 = Console.ReadLine();
double cleanNum1 = 0;
while (!double.TryParse(numInput1, out cleanNum1))
{
Console.Write("This is not valid input. Please enter an integer value: ");
numInput1 = Console.ReadLine();
}
// Ask the user to type the second number.
Console.Write("Type another number, and then press Enter: ");
numInput2 = Console.ReadLine();
double cleanNum2 = 0;
while (!double.TryParse(numInput2, out cleanNum2))
{
Console.Write("This is not valid input. Please enter an integer value: ");
numInput2 = Console.ReadLine();
}
// Ask the user to choose an operator.
Console.WriteLine("Choose an operator from the following list:");
Console.WriteLine("\ta - Add");
Console.WriteLine("\ts - Subtract");
Console.WriteLine("\tm - Multiply");
Console.WriteLine("\td - Divide");
Console.Write("Your option? ");
string op = Console.ReadLine();
try
{
result = calculator.DoOperation(cleanNum1, cleanNum2, op);
if (double.IsNaN(result))
{
Console.WriteLine("This operation will result in a mathematical error.\n");
}
else Console.WriteLine("Your result: {0:0.##}\n", result);
}
catch (Exception e)
{
Console.WriteLine("Oh no! An exception occurred trying to do the math.\n - Details: " + e.Message);
}
Console.WriteLine("------------------------\n");
// Wait for the user to respond before closing.
Console.Write("Press 'n' and Enter to close the app, or press any other key and Enter to continue: ");
if (Console.ReadLine() == "n") endApp = true;
Console.WriteLine("\n"); // Friendly linespacing.
}
calculator.Finish();
return;
}
}
}
Oto kompletny kod pliku CalculatorLibrary.cs po wykonaniu wszystkich kroków:
using Newtonsoft.Json;
namespace CalculatorLibrary
{
public class Calculator
{
JsonWriter writer;
public Calculator()
{
StreamWriter logFile = File.CreateText("calculatorlog.json");
logFile.AutoFlush = true;
writer = new JsonTextWriter(logFile);
writer.Formatting = Formatting.Indented;
writer.WriteStartObject();
writer.WritePropertyName("Operations");
writer.WriteStartArray();
}
public double DoOperation(double num1, double num2, string op)
{
double result = double.NaN; // Default value is "not-a-number" if an operation, such as division, could result in an error.
writer.WriteStartObject();
writer.WritePropertyName("Operand1");
writer.WriteValue(num1);
writer.WritePropertyName("Operand2");
writer.WriteValue(num2);
writer.WritePropertyName("Operation");
// Use a switch statement to do the math.
switch (op)
{
case "a":
result = num1 + num2;
writer.WriteValue("Add");
break;
case "s":
result = num1 - num2;
writer.WriteValue("Subtract");
break;
case "m":
result = num1 * num2;
writer.WriteValue("Multiply");
break;
case "d":
// Ask the user to enter a non-zero divisor.
if (num2 != 0)
{
result = num1 / num2;
}
writer.WriteValue("Divide");
break;
// Return text for an incorrect option entry.
default:
break;
}
writer.WritePropertyName("Result");
writer.WriteValue(result);
writer.WriteEndObject();
return result;
}
public void Finish()
{
writer.WriteEndArray();
writer.WriteEndObject();
writer.Close();
}
}
}
Oto kod pliku 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;
}
}
}
Następne kroki
Gratulujemy ukończenia tego samouczka! Aby dowiedzieć się więcej, kontynuuj pracę z następującą zawartością:
- Kontynuuj korzystanie z kolejnych samouczków dotyczących języka C#
- Szybki start: tworzenie aplikacji internetowej ASP.NET Core
- Dowiedz się, jak debugować kod języka C# w programie Visual Studio
- Zapoznaj się z instrukcjami tworzenia i uruchamiania testów jednostkowych
- Uruchamianie programu w języku C#
- Dowiedz się więcej o funkcji IntelliSense w języku C#
- Kontynuuj pracę z omówieniem środowiska IDE programu Visual Studio
- Rejestrowanie i śledzenie