练习 - 在 C# 控制台应用程序中引发和捕获异常
在本练习中,在顶级语句中开发 try 代码块和 catch 子句,在 MakeChange 方法中创建并引发异常,然后使用异常对象完成 catch 代码块。 在本练习中,完成以下任务:
- 更新顶级语句:在顶级语句中实现
try-catch模式。try代码块将包含对MakeChange的调用。 - 更新
MakeChange方法:对“出纳机现金不足”和“付款不足”问题创建并引发异常。 - 更新
catch代码块以使用引发的异常的属性。 - 验证测试:对在本练习中开发的代码执行验证测试。
向顶级语句添加 try-catch 模式
在此任务中,在 MakeChange 语句中包含对 try 方法的调用,并创建相应的 catch 子句。
在 Visual Studio Code 编辑器中,确保已打开 Program.cs 文件。
找到以下代码行:
// MakeChange manages the transaction and updates the till string transactionMessage = MakeChange(itemCost, cashTill, paymentTwenties, paymentTens, paymentFives, paymentOnes); // Backup Calculation - each transaction adds current "itemCost" to the till if (transactionMessage == "transaction succeeded") { Console.WriteLine($"Transaction successfully completed."); registerCheckTillTotal += itemCost; } else { Console.WriteLine($"Transaction unsuccessful: {transactionMessage}"); }花一点时间考虑此代码的用途。
请注意,
MakeChange返回一个字符串值。 返回值会分配给名为transactionMessage的变量。 如果transactionMessage等于“交易成功”,则所购物品的成本将添加到registerCheckTillTotal。 变量registerCheckTillTotal用于验证通过MakeChange方法计算的出纳机余额。若要将对
MakeChange方法的调用包含在try语句代码块中,请更新代码,如下所示:try { // MakeChange manages the transaction and updates the till string transactionMessage = MakeChange(itemCost, cashTill, paymentTwenties, paymentTens, paymentFives, paymentOnes); }在
catch语句代码块后,添加以下try子句:catch { }创建并引发异常后,便完成了
catch子句的开发。
在 MakeChange 方法中创建并引发异常
在此任务中,更新 MakeChange 以在交易无法完成时创建和引发自定义异常。
MakeChange 方法包括两个应导致异常的问题:
“付款不足”问题:当客户提供的付款少于物品成本时,就会出现此问题。 如果客户未提供足够的付款,
MakeChange应引发异常。“出纳机现金不足”问题:当出纳机中没有准确找零所需的纸币时,就会出现此问题。 如果出纳机不能准确找零,
MakeChange应引发异常。
向下滚动到
MakeChange方法。找到以下代码行:
if (changeNeeded < 0) transactionMessage = "Not enough money provided.";花一点时间考虑此代码要解决的问题。
如果
changeNeeded小于零,则客户没有提供足够的资金来支付其所购物品的购买价格。 购买价格和客户提供的资金是MakeChange方法的参数。 当客户未提供足够的资金时,该方法无法完成交易。 换句话说,操作失败。有两种异常类型似乎与以下条件匹配:
-
InvalidOperationException:只有当方法的操作条件不支持成功完成特定方法调用时,才应引发InvalidOperationException异常。 在这种情况下,操作条件由提供给该方法的参数确定。 -
ArgumentOutOfRangeException- 只有当自变量的值超出了所调用方法定义的允许值范围时,才应引发ArgumentOutOfRangeException异常。 在这种情况下,提供的资金必须大于物品的成本。
任一异常类型都可工作,但
InvalidOperationException在此应用程序的上下文中稍微更合适一些。-
按如下所示更新代码:
if (changeNeeded < 0) throw new InvalidOperationException("InvalidOperationException: Not enough money provided to complete the transaction.");向下滚动以找到以下代码行:
if (changeNeeded > 0) transactionMessage = "Can't make change. Do you have anything smaller?";花一点时间考虑此代码要解决的问题。
如果
changeNeeded在准备找零的while循环后大于零,则出纳机中可用于找零的纸币已经用完。 当出纳机缺少找零所需的纸币时,该方法不能完成交易。 换句话说,操作失败。应使用
InvalidOperationException异常来创建异常。按如下所示更新代码:
if (changeNeeded > 0) throw new InvalidOperationException("InvalidOperationException: The till is unable to make the correct change.");
完成 catch 代码块
在此任务中,更新 catch 子句以捕获特定的异常类型。
向上滚动到
MakeChange方法上方,找到以下代码:catch { }若要捕获
MakeChange方法中引发的异常类型,请更新代码,如下所示:catch (InvalidOperationException e) { Console.WriteLine($"Could not complete transaction: {e.Message}"); }将捕获
InvalidOperationException中引发的MakeChange异常对象,但不会捕获其他异常类型。 由于你尚未准备好处理其他异常类型,因此请务必使它们在调用堆栈中较低位置被捕获。 如果发现MakeChange中预期有其他异常类型,可添加其他catch子句。使用“文件”菜单保存更新。
将 MakeChange 方法从“string”转换为“void”并访问异常属性
在此任务中,将 MakeChange 更新为 void 类型,然后使用异常属性向用户传达问题详细信息。
滚动到
MakeChange方法的顶部。若要将
MakeChange方法从string类型转换为void类型,请更新代码,如下所示:static void MakeChange(int cost, int[] cashTill, int twenties, int tens = 0, int fives = 0, int ones = 0)删除以下变量声明:
string transactionMessage = "";滚动到
MakeChange方法的底部。删除以下代码行:
if (transactionMessage == "") transactionMessage = "transaction succeeded"; return transactionMessage;向上滚动到顶级语句并找到
try代码块。按如下所示更新
try代码块:try { // MakeChange manages the transaction and updates the till MakeChange(itemCost, cashTill, paymentTwenties, paymentTens, paymentFives, paymentOnes); Console.WriteLine($"Transaction successfully completed."); registerCheckTillTotal += itemCost; }找到并删除以下代码行:
// Backup Calculation - each transaction adds current "itemCost" to the till if (transactionMessage == "transaction succeeded") { Console.WriteLine($"Transaction successfully completed."); registerCheckTillTotal += itemCost; } else { Console.WriteLine($"Transaction unsuccessful: {transactionMessage}"); }try和catch代码块现在向用户传达交易“成功”和“失败”消息。 由于异常的Message属性描述了该问题,因此一条Console.WriteLine()语句可同时解决这两个问题。 经过这些更新后,代码更易于阅读和维护。使用“文件”菜单保存更新。
检查你的工作
在此任务中,运行应用程序并验证更新的代码按预期工作。
向上滚动以在顶级语句中查找
while循环。此循环用于循环访问交易。
在
while循环开始前几行,找到以下代码。int transactions = 10;将交易数更新为
40,如下所示:int transactions = 40;在
while循环中找到以下代码行。int itemCost = valueGenerator.Next(2, 20);按如下所示更新
itemCost随机数生成器:int itemCost = valueGenerator.Next(2, 50);此成本范围更适合客户将购买的物品。
使用“文件”菜单保存更新。
在“运行”菜单上,选择“开始调试”。
在“终端”面板中查看输出。
验证显示了与两种异常类型关联的消息:
交易报告应包含以下“无法完成交易”消息:
Customer is making a $42 purchase Using 2 twenty dollar bills Using 0 ten dollar bills Using 0 five dollar bills Using 0 one dollar bills Could not complete transaction: InvalidOperationException: Not enough money provided to complete the transaction.Customer is making a $23 purchase Using 2 twenty dollar bills Using 0 ten dollar bills Using 0 five dollar bills Using 1 one dollar bills Cashier prepares the following change: A five A five A one A one Could not complete transaction: InvalidOperationException: The till is unable to make change for the cash provided.
恭喜,你已调试现金出纳机应用程序以修复代码逻辑问题,并且已更新应用程序以使用适当的异常处理技术。
注意
报告的输出显示,现金出纳机余额不足。 代码中还存在其他逻辑 bug。 如果有兴趣演示 Visual Studio Code 调试技能,可以使用挑战项目模块!