Poznámka
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Ve 2. části této série kurzů se podrobněji ponoříte do sestavení a ladění funkcí sady Visual Studio, které potřebujete pro každodenní vývoj. Mezi tyto funkce patří správa více projektů, ladění a odkazování na balíčky třetích stran. Spustíte konzolovou aplikaci jazyka C#, kterou jste vytvořili v části 1 tohoto kurzu, a prozkoumáte některé funkce integrovaného vývojového prostředí (IDE) sady Visual Studio. Tento kurz je druhou částí dvoudílné série kurzů.
V tomto kurzu dokončíte následující úlohy:
- Přidejte druhý projekt.
- Odkazovat na knihovny a přidávat balíčky
- Ladění kódu
- Zkontrolujte dokončený kód.
Požadavky
K práci s tímto článkem můžete použít některou z těchto aplikací kalkulačky:
- Konzolová kalkulačka z části 1 tohoto kurzu.
- Kalkulačka v jazyce C# v úložišti vs-tutorial-samples . Začněte tím, že aplikaci otevřete zúložiště .
Přidání dalšího projektu
Skutečný kód zahrnuje projekty, které spolupracují v řešení. Do aplikace kalkulačky můžete přidat projekt knihovny tříd, který poskytuje některé funkce kalkulačky.
Příkaz nabídky Soubor>Přidat>Nový projekt v sadě Visual Studio slouží k přidání nového projektu. Můžete také kliknout pravým tlačítkem na řešení v Průzkumníku řešení a přidat projekt z místní nabídky.
V Průzkumníku řešeníklikněte pravým tlačítkem na uzel řešení a zvolte Přidat>Nový projekt.
V okně Přidat nový projekt zadejte do vyhledávacího pole knihovnu tříd. Zvolte šablonu projektu knihovna tříd C# a pak vyberte Další.
Na obrazovce Konfigurovat nový projekt zadejte název projektu CalculatorLibrarya poté vyberte Další.
Po zobrazení výzvy zvolte .NET 3.1. Visual Studio vytvoří nový projekt a přidá ho do řešení.
Přejmenujte soubor Class1.cs na CalculatorLibrary.cs. Pokud chcete soubor přejmenovat, můžete kliknout pravým tlačítkem myši na název v průzkumníku řešení a zvolit Přejmenovat, vybrat název a stisknout F2nebo vybrat název a znovu zadat.
Zpráva se může zeptat, jestli chcete přejmenovat odkazy na
Class1
v souboru. Nezáleží na tom, jak odpovíte, protože kód nahradíte v budoucím kroku.Teď přidejte odkaz na projekt, takže první projekt může používat rozhraní API, která nová knihovna tříd zveřejňuje. Pravým tlačítkem myši klikněte na uzel Závislostí v projektu Kalkulačka a zvolte možnost Přidat projektovou referenci.
Zobrazí se dialogové okno Správce odkazů. V tomto dialogovém okně můžete přidat odkazy na jiné projekty, sestavení a knihovny DLL modelu COM, které vaše projekty potřebují.
V dialogovém okně Správce odkazů zaškrtněte políčko u projektu CalculatorLibrary a pak vyberte OK.
Odkaz na projekt se zobrazí pod uzlem Projekty v Průzkumníku řešení .
V Program.csvyberte třídu
Calculator
a veškerý jeho kód a stisknutím klávesy Ctrl+X ho vyjměte. Potom do CalculatorLibrary.csvložte kód do oboru názvůCalculatorLibrary
.Přidejte také
public
před třídu Calculator, aby ji zpřístupnila mimo knihovnu.CalculatorLibrary.cs by se teď měl podobat následujícímu kódu:
// CalculatorLibrary.cs 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 má také referenci, ale chyba uvádí, že volání
Calculator.DoOperation
se nevyřeší. Příčinou této chyby je, žeCalculatorLibrary
je v jiném oboru názvů. Pro plně kvalifikovaný odkaz můžete přidat obor názvůCalculatorLibrary
do voláníCalculator.DoOperation
v Program.cs:// Program.cs result = CalculatorLibrary.Calculator.DoOperation(cleanNum1, cleanNum2, op);
Nebo můžete zkusit přidat direktivu
using
na začátek souboru Program.cs:// Program.cs using CalculatorLibrary;
Přidáním direktivy
using
můžete odebrat obor názvůCalculatorLibrary
z místa volání, ale teď existuje nejednoznačnost. Je třídaCalculator
vCalculatorLibrary
, nebo jeCalculator
jmenný prostor?Chcete-li vyřešit nejednoznačnost, přejmenujte obor názvů z
Calculator
naCalculatorProgram
v Program.cs.// Program.cs namespace CalculatorProgram
V Průzkumníku řešeníklikněte pravým tlačítkem na uzel řešení a zvolte Přidat>Nový projekt.
V okně Přidat nový projekt zadejte do vyhledávacího pole knihovnu tříd. Zvolte šablonu projektu knihovna tříd C# a pak vyberte Další.
Na obrazovce Konfigurovat nový projekt zadejte název projektu CalculatorLibrarya poté vyberte Další.
Na obrazovce Další informace je vybraná .NET 8.0. Vyberte Vytvořit.
Visual Studio vytvoří nový projekt a přidá ho do řešení.
Přejmenujte soubor Class1.cs na CalculatorLibrary.cs. Pokud chcete soubor přejmenovat, můžete kliknout pravým tlačítkem myši na název v průzkumníku řešení a zvolit Přejmenovat, vybrat název a stisknout F2nebo vybrat název a znovu zadat.
Zpráva se může zeptat, jestli chcete přejmenovat všechny odkazy na
Class1
v souboru. Nezáleží na tom, jak odpovíte, protože kód nahradíte v budoucím kroku.Teď přidejte odkaz na projekt, takže první projekt může používat rozhraní API, která nová knihovna tříd zveřejňuje. Pravým tlačítkem myši klikněte na uzel Závislostí v projektu Kalkulačka a zvolte možnost Přidat projektovou referenci.
Zobrazí se dialogové okno Správce odkazů. V tomto dialogovém okně můžete přidat odkazy na jiné projekty, sestavení a knihovny DLL modelu COM, které vaše projekty potřebují.
V dialogovém okně Správce odkazů zaškrtněte políčko u projektu CalculatorLibrary a pak vyberte OK.
Odkaz na projekt se zobrazí pod uzlem Projekty v Průzkumníku řešení .
V Program.csvyberte třídu
Calculator
a veškerý jeho kód a stisknutím klávesy Ctrl+X ho vyjměte. Potom do CalculatorLibrary.csvložte kód do oboru názvůCalculatorLibrary
.Přidejte také
public
před třídu Calculator, aby ji zpřístupnila mimo knihovnu.CalculatorLibrary.cs by se teď měl podobat následujícímu kódu:
// CalculatorLibrary.cs 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 má také referenci, ale chyba uvádí, že volání
Calculator.DoOperation
se nevyřeší. Příčinou této chyby je, žeCalculatorLibrary
je v jiném oboru názvů. Pro plně kvalifikovaný odkaz můžete přidat obor názvůCalculatorLibrary
do voláníCalculator.DoOperation
v Program.cs:// Program.cs result = CalculatorLibrary.Calculator.DoOperation(cleanNum1, cleanNum2, op);
Nebo můžete zkusit přidat direktivu
using
na začátek souboru Program.cs:// Program.cs using CalculatorLibrary;
Přidáním direktivy
using
byste měli odebrat obor názvůCalculatorLibrary
z lokality volání.Pokud je váš kód
Program.cs
v oboru názvůCalculator
, přejmenujte obor názvů zCalculator
naCalculatorProgram
, aby se odstranila nejednoznačnost mezi názvem třídy a názvem oboru názvů.
Referenční knihovny .NET: Zápis do protokolu
Pomocí třídy Trasování .NET můžete přidat protokol všech operací a zapsat ho do textového souboru. Třída Trace
je také užitečná pro základní techniky ladění tisku. Třída Trace
je v System.Diagnostics
a používá System.IO
třídy, jako je StreamWriter
.
Začněte přidáním direktiv
using
v horní části CalculatorLibrary.cs:// CalculatorLibrary.cs using System.IO; using System.Diagnostics;
Toto použití
Trace
třídy musí obsahovat odkaz na třídu, kterou přidruží k filestreamu. Tento požadavek znamená, že kalkulačka funguje lépe jako objekt, takže přidejte konstruktor na začátek třídyCalculator
v CalculatorLibrary.cs.Odeberte také klíčové slovo
static
a změňte statickou metoduDoOperation
na metodu instance.// CalculatorLibrary.cs 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) {
Přidejte výstup protokolu do každého výpočtu.
DoOperation
by teď měl vypadat jako následující kód:// CalculatorLibrary.cs 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; }
Zpět v Program.csnyní červená vlnovka označuje problém se statickým voláním. Pokud chcete chybu opravit, vytvořte proměnnou
calculator
přidáním následujícího řádku kódu těsně před smyčkuwhile (!endApp)
:// Program.cs Calculator calculator = new Calculator();
Upravte také web volání
DoOperation
tak, aby odkazoval na objekt s názvemcalculator
malými písmeny. Kód je nyní vyvoláním člena, nikoli voláním statické metody.// Program.cs result = calculator.DoOperation(cleanNum1, cleanNum2, op);
Spusťte aplikaci znovu. Po dokončení klikněte pravým tlačítkem na uzel projektu Kalkulačka a zvolte Otevřít složku ve Průzkumníku souborů.
V Průzkumníku souborů přejděte do výstupní složky ve složce bin/Debug/net8.0 (nebo jakoukoli verzi .NET, kterou používáte) a otevřete soubor calculator.log. Výstup by měl vypadat přibližně takto:
Starting Calculator Log Started 7/9/2020 1:58:19 PM 1 + 2 = 3 3 * 3 = 9
V tomto okamžiku by měl CalculatorLibrary.cs vypadat podobně jako tento kód:
// CalculatorLibrary.cs
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 by měl vypadat jako následující kód:
// 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.
}
return;
}
}
}
Pomocí třídy Trasování .NET můžete přidat protokol všech operací a zapsat ho do textového souboru. Třída Trace
je také užitečná pro základní techniky ladění tisku. Třída Trace
je v System.Diagnostics
a používá System.IO
třídy, jako je StreamWriter
.
Začněte přidáním direktiv
using
v horní části CalculatorLibrary.cs:// CalculatorLibrary.cs using System.Diagnostics;
Toto použití
Trace
třídy musí obsahovat odkaz na třídu, kterou přidruží k filestreamu. Tento požadavek znamená, že kalkulačka funguje lépe jako objekt, takže přidejte konstruktor na začátek třídyCalculator
v CalculatorLibrary.cs.Odeberte také klíčové slovo
static
a změňte statickou metoduDoOperation
na metodu instance.// CalculatorLibrary.cs 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) {
Přidejte výstup protokolu do každého výpočtu.
DoOperation
by teď měl vypadat jako následující kód:// CalculatorLibrary.cs 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; }
Zpět v Program.csnyní červená vlnovka označuje problém se statickým voláním. Pokud chcete chybu opravit, vytvořte proměnnou
calculator
přidáním následujícího řádku kódu těsně před smyčkuwhile (!endApp)
:// Program.cs Calculator calculator = new Calculator();
Upravte také web volání
DoOperation
tak, aby odkazoval na objekt s názvemcalculator
malými písmeny. Kód je nyní vyvoláním člena, nikoli voláním statické metody.// Program.cs result = calculator.DoOperation(cleanNum1, cleanNum2, op);
Spusťte aplikaci znovu. Po dokončení klikněte pravým tlačítkem na uzel projektu Kalkulačka a zvolte Otevřít složku ve Průzkumníku souborů.
V Průzkumníku souborů přejděte do výstupní složky v části bin/Debug/a otevřete soubor calculator.log. Výstup by měl vypadat přibližně takto:
Starting Calculator Log Started 7/9/2020 1:58:19 PM 1 + 2 = 3 3 * 3 = 9
V tomto okamžiku by měl CalculatorLibrary.cs vypadat podobně jako tento kód:
// CalculatorLibrary.cs
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 by měl vypadat jako následující kód:
// 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.
// Use Nullable types (with ?) to match type of System.Console.ReadLine
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();
// Validate input is not null, and matches the pattern
if (op == null || ! Regex.IsMatch(op, "[a|s|m|d]"))
{
Console.WriteLine("Error: Unrecognized input.");
}
else
{
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;
}
}
}
Přidání balíčku NuGet: Zápis do souboru JSON
Pro výstup operací ve formátu JSON, oblíbeném a přenosném formátu pro ukládání dat objektů, můžete použít balíček NuGet Newtonsoft.Json. Balíčky NuGet jsou primární distribuční metodou pro knihovny tříd .NET.
V Průzkumníku řešeníklikněte pravým tlačítkem na uzel Závislostí projektu CalculatorLibrary a zvolte Spravovat balíčky NuGet.
Otevře se Správce balíčků NuGet.
Vyhledejte a vyberte balíček Newtonsoft.Json a vyberte Nainstalovat.
Visual Studio stáhne balíček a přidá ho do projektu. V Průzkumníku řešení se objeví nová položka ve složce Reference .
Pokud se zobrazí výzva k přijetí změn, vyberte OK.
Visual Studio stáhne balíček a přidá ho do projektu. Nová položka se zobrazí v uzlu Packages v Průzkumníku řešení .
Na začátek
using
přidejte direktivuNewtonsoft.Json
pro .// CalculatorLibrary.cs using Newtonsoft.Json;
Vytvořte
JsonWriter
objekt člena a nahraďte konstruktorCalculator
následujícím kódem:// CalculatorLibrary.cs 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(); }
Upravte metodu
DoOperation
a přidejte kódwriter
JSON:// CalculatorLibrary.cs 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; }
Po zadání dat operace přidejte metodu pro dokončení syntaxe JSON.
// CalculatorLibrary.cs public void Finish() { writer.WriteEndArray(); writer.WriteEndObject(); writer.Close(); }
Na konci Program.cs, před
return;
, přidejte volání naFinish
:// Program.cs // Add call to close the JSON writer before return calculator.Finish(); return; }
Sestavte a spusťte aplikaci a po zadání několika operací zavřete aplikaci zadáním příkazu n.
Otevřete soubor calculatorlog.json v Průzkumníku souborů. Měli byste vidět něco jako následující obsah:
{ "Operations": [ { "Operand1": 2.0, "Operand2": 3.0, "Operation": "Add", "Result": 5.0 }, { "Operand1": 3.0, "Operand2": 4.0, "Operation": "Multiply", "Result": 12.0 } ] }
Ladění: Nastavení a aktivace bodu přerušení
Ladicí program sady Visual Studio je výkonný nástroj. Ladicí program může procházet kód a najít přesný bod, kde je chyba programování. Pak můžete pochopit, jaké opravy potřebujete udělat, a provést dočasné změny, abyste mohli pokračovat ve spuštění aplikace.
V Program.csklikněte do okraje vlevo od následujícího řádku kódu. Můžete také kliknout na řádek a vybrat F9, nebo kliknout pravým tlačítkem myši na řádek a vybrat Zarážku>Vložit zarážku.
// Program.cs result = calculator.DoOperation(cleanNum1, cleanNum2, op);
Červená tečka, která se zobrazí, značí zarážku. Zarážky můžete použít k pozastavení aplikace a kontrole kódu. Zarážku můžete nastavit na libovolný spustitelný řádek kódu.
Sestavte a spusťte aplikaci. Zadejte následující hodnoty pro výpočet:
- Jako první číslo zadejte 8.
- Jako druhé číslo zadejte 0.
- Pro operátora, pojďme se trochu pobavit. Zadejte d.
Aplikace pozastaví místo, kde jste vytvořili zarážku, která je označená žlutým ukazatelem vlevo a zvýrazněným kódem. Zvýrazněný kód se ještě nespustí.
Teď můžete s pozastavenou aplikací zkontrolovat stav aplikace.
Ladění: Zobrazení proměnných
Ve zvýrazněném kódu najeďte myší na proměnné, jako jsou
cleanNum1
aop
. Aktuální hodnoty těchto proměnných8
ad
se zobrazí v datových tipech.Při ladění zkontrolujte, jestli proměnné obsahují očekávané hodnoty, často důležité pro řešení problémů.
V dolním podokně se podívejte na panel Místní. Pokud je zavřený, otevřete ho výběrem Ladění>>Místní prostředí systému Windows.
Okno Locals zobrazuje každou proměnnou, která je právě v dosahu, spolu s její hodnotou a typem.
Podívejte se do okna Aut.
Okno Automatické položky je podobné místním okně, ale zobrazuje proměnné bezprostředně před aktuálním řádkem kódu, kde je aplikace pozastavená.
Poznámka
Pokud nevidíte okno Automatické, otevřete ho výběrem Ladit>Windows>Automatické.
Dále spusťte kód v ladicím programu po jednom příkazu, který se nazývá krokování.
Ladění: Procházení kódu kroky
Stiskněte F11 nebo vyberte Ladit>krok do.
Pomocí příkazu Step Into spustí aplikace aktuální příkaz a přejde na další spustitelný příkaz, obvykle další řádek kódu. Žlutý ukazatel vlevo vždy označuje aktuální příkaz.
Právě jste přešli do metody
DoOperation
ve tříděCalculator
.Pokud chcete získat hierarchický pohled na tok programu, podívejte se do okna zásobníku volání. Pokud je zavřený, otevřete ho výběrem ladění>Windows>zásobník volání.
Toto zobrazení zobrazuje aktuální metodu
Calculator.DoOperation
označenou žlutým ukazatelem. Druhý řádek ukazuje funkci, která volala metodu, z metodyMain
v Program.cs.Okno Zásobník volání zobrazuje pořadí volání metod a funkcí. Toto okno také poskytuje přístup k mnoha funkcím ladicího programu, jako je z místní nabídky Přejít na zdrojový kód.
Stiskněte F10nebo vyberte několikrát Ladit>Krok přes, dokud se aplikace nezastaví u příkazu
switch
.// CalculatorLibrary.cs switch (op) {
Příkaz Krok přes je podobný příkazu Krok dovnitř, s tím rozdílem, že pokud aktuální příkaz volá funkci, ladicí program spustí kód ve funkci a nepozastaví provádění, dokud funkce nevrátí. Krok za krokem je rychlejší než krok do, pokud vás konkrétní funkce nezajímá.
Stiskněte F10 ještě jednou, aby se aplikace pozastavila na následujícím řádku kódu.
// CalculatorLibrary.cs if (num2 != 0) {
Tento kód kontroluje případ dělení nulou. Pokud aplikace pokračuje, vyvolá obecnou výjimku (chybu), ale můžete zkusit něco jiného, třeba zobrazit skutečnou vrácenou hodnotu v konzole. Jednou z možností je použít funkci ladicího programu zvanou upravovat a pokračovat k provádění změn v kódu a následnému pokračování v ladění. Existuje ale jiný trik k dočasné úpravě toku provádění.
Ladění: Testování dočasné změny
Vyberte žlutý ukazatel, který je aktuálně pozastavený na příkazu
if (num2 != 0)
, a přetáhněte ho do následujícího příkazu:// CalculatorLibrary.cs result = num1 / num2;
Přetažením ukazatele sem aplikace úplně přeskočí příkaz
if
, abyste viděli, co se stane, když vydělíte nulou.Stisknutím klávesy F10 spusťte řádek kódu.
Pokud najedete myší na proměnnou
result
, zobrazí se hodnota Infinity. V jazyce C# je výsledkem nekonečna při dělení nulou.Stiskněte F5 nebo vyberte Ladění>Pokračovat v ladění.
Symbol nekonečna se v konzole zobrazí jako výsledek matematické operace.
Aplikaci zavřete správně zadáním příkazu n.
Kód je dokončený.
Tady je úplný kód souboru CalculatorLibrary.cs po dokončení všech kroků:
// CalculatorLibrary.cs
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();
}
}
}
A tady je kód pro Program.cs:
// 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;
}
}
}
Tady je úplný kód souboru CalculatorLibrary.cs po dokončení všech kroků:
// CalculatorLibrary.cs
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();
}
}
}
A tady je kód pro Program.cs:
// 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.
// Use Nullable types (with ?) to match type of System.Console.ReadLine
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();
// Validate input is not null, and matches the pattern
if (op == null || ! Regex.IsMatch(op, "[a|s|m|d]"))
{
Console.WriteLine("Error: Unrecognized input.");
}
else
{
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;
}
}
}
Další kroky
Blahopřejeme k dokončení tohoto kurzu! Další informace najdete v následujícím obsahu:
- Pokračovat v dalších kurzech jazyka C#
- Rychlý start: Vytvoření webové aplikace ASP.NET Core
- Naučte se ladit kód jazyka C# v sadě Visual Studio
- Projděte si, jak vytvářet a spouštět testy jednotek
- Spuštění programu v jazyce C#
- Informace o IntelliSense v jazyce C#
- Pokračovat v přehledu integrovaného vývojového prostředí sady Visual Studio
- protokolování a trasování