Topics on Exception Handling
Topics on Exception Handling
Handling many Exceptions
Catching Various Exceptions
In previous examples (in the previous lesson), when we anticipated some type of problem, we instructed the compiler to use our default catch section. We left it up to the compiler to find out when there was a problem and we provided a catch section to deal with it. A section of code with numerous or complex operations and requests can also produce different types of errors. You should be able to face different problems and deal with them individually, each by its own kind. To do this, you can create different catch sections, each made for a particular error. The formula to follow is:
try { // Code to Try } catch(arg1) { // One Exception } catch(arg2) { // Another Exception }
The compiler would proceed from top-down:
Multiple catch clauses are written if or when a try block is expected to throw different types of errors.
Practical Learning: Introducing Exception Handling
namespace PayrollPreparation6.Models { internal class Employee { internal int EmployeeNumber { get; set; } internal string? FirstName { get; set; } internal string? LastName { get; set; } internal double HourlySalary { get; set; } } }
namespace PayrollPreparation6.Models { internal class TimeSheet { private int tsNbr; private int empl; private double salary; private double result; private double mon, tue, wed, thu, fri; internal TimeSheet(int ts, int emplNbr, double m, double t, double w, double h, double f) { mon = m; tue = t; wed = w; thu = h; fri = f; tsNbr = ts; empl = emplNbr; } internal ref int GetTimeSheetNumber() => ref tsNbr; internal ref int GetEmployeeNumber() => ref empl; internal ref double GetMondayWork() => ref mon; internal ref double GetTuesdayWork() => ref tue; internal ref double GetWednesdayWork() => ref wed; internal ref double GetThursdayWork() => ref thu; internal ref double GetFridayWork() => ref fri; private ref double GetSalary() { salary = 0.00; if (empl == 370_595) { salary = 28.25; } else if (empl == 395_796) { salary = 18.86; } else if (empl == 826_384) { salary = 24.37; } else if (empl == 175_004) { salary = 26.97; } else if (empl == 697_415) { salary = 31.57; } else salary = 0.00; return ref salary; } internal double CalculateTimeWorked() => mon + tue + wed + thu + fri; internal ref double CalculateRegularTime(ref readonly double time) { result = time; if (time is > 40.00) { result = 40.00; } return ref result; } internal ref double CalculateRegularPay(ref readonly double time) { result = GetSalary() * time; if (time is > 40.00) { result = GetSalary() * 40.00; } return ref result; } internal ref double CalculateOvertime(ref readonly double time) { result = 0.00; if (time is > 40.00) { result = time - 40.00; } return ref result; } internal ref double CalculateOvertimePay(ref readonly double time) { result = 0.00; if (time is > 40.00) { result = salary * 1.50 * time; } return ref result; } internal double CalculateGrossPay(ref double time) => CalculateRegularPay(ref time) + CalculateOvertimePay(ref time); } }
using PayrollPreparation6.Models; using static System.Console; PreparePayroll(); Employee Hire(in int number) { Employee empl1 = new Employee() { EmployeeNumber = 370_595, FirstName = "Michael", LastName = "Carlock", HourlySalary = 28.25 }; Employee empl2 = new Employee() { EmployeeNumber = 826_384, FirstName = "Catherine", LastName = "Busbey", HourlySalary = 24.37 }; Employee empl3 = new Employee() { EmployeeNumber = 175_004, FirstName = "Andrew", LastName = "Sanders", HourlySalary = 26.97 }; Employee empl4 = new Employee() { EmployeeNumber = 697_415, FirstName = "Jennifer", LastName = "Simms", HourlySalary = 31.57 }; Employee empl5 = new Employee() { EmployeeNumber = 395_796, FirstName = "Richard", LastName = "Stones", HourlySalary = 18.86 }; if (number == 370_595) { return empl1; } else if (number == 826_384) { return empl2; } else if (number == 175_004) { return empl3; } else if (number == 697_415) { return empl4; } else if (number == 395_796) { return empl5; } return new Employee(); } TimeSheet GetTimeWorked(in int number) { TimeSheet ts1 = new TimeSheet(100_000, 370_595, 7, 8, 6.5, 8.5, 6.5); TimeSheet ts2 = new TimeSheet(205_000, 826_384, 9.5, 8, 10.5, 9, 8.5); TimeSheet ts3 = new TimeSheet(505_500, 175_004, 9, 10.5, 7, 9.5, 8.5); TimeSheet ts4 = new TimeSheet(202_240, 697_415, 8, 8, 8, 8, 8); TimeSheet ts5 = new TimeSheet(693_748, 395_796, 8, 6.5, 7, 9, 6); if (number == 205_000) { return ts2; } else if (number == 202_240) { return ts4; } else if (number == 505_500) { return ts3; } else if (number == 693_748) { return ts5; } else if (number == 100_000) { return ts1; } return new TimeSheet(0, 0, 0, 0, 0, 0, 0); } void PreparePayroll() { try { Write("Enter the Id of the time sheet to view: "); int nbr = int.Parse(ReadLine()!); TimeSheet timeSheet = GetTimeWorked(nbr); int emplNumber = timeSheet.GetEmployeeNumber(); Employee staff = Hire(emplNumber); WriteLine("+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+"); WriteLine("FUN DEPARTMENT STORE"); WriteLine("======================================================="); WriteLine("Payroll Evaluation"); WriteLine("======================================================="); ShowEmployee(ref staff); PresentPayroll(ref timeSheet); } catch(FormatException fe) { WriteLine("--------------------------------------------------------------"); WriteLine("The number you provided for the time sheet to view is not valid."); WriteLine("The error produced is: " + fe.Message); WriteLine("=============================================================="); } catch (Exception exc) { WriteLine("--------------------------------------------------------------"); WriteLine("There was an error in your application. The error produced is:"); WriteLine(exc.Message); WriteLine("=============================================================="); } } void ShowEmployee(ref readonly Employee empl) { WriteLine("Employee Information"); WriteLine("-------------------------------------------------------"); WriteLine("Employee #: {0}", empl.EmployeeNumber); WriteLine($"Full Name: {empl.FirstName} {empl.LastName}"); WriteLine($"Hourly Salary: {empl.HourlySalary:f}"); WriteLine("======================================================="); } void PresentPayroll(ref readonly TimeSheet ts) { double timeWorked = ts.CalculateTimeWorked(); WriteLine("Time Sheet #: {0}", ts.GetTimeSheetNumber()); WriteLine("-------------------------------------------------------"); WriteLine("Time Worked Summary"); WriteLine("--------+---------+-----------+----------+-------------"); WriteLine(" Monday | Tuesday | Wednesday | Thursday | Friday"); WriteLine("--------+---------+-----------+----------+-------------"); Write($" {ts.GetMondayWork():f} | "); Write($"{ts.GetTuesdayWork():f} | "); Write($"{ts.GetWednesdayWork():f} | "); Write($"{ts.GetThursdayWork():f} | "); WriteLine($"{ts.GetFridayWork():f}"); WriteLine("========+=========+===========+==========+============="); WriteLine(" Pay Summary"); WriteLine("-------------------------------------------------------"); WriteLine(" Time Pay"); WriteLine("-------------------------------------------------------"); WriteLine(" Regular: {0:f} {1:f}", ts.CalculateRegularTime(ref timeWorked), ts.CalculateRegularPay(ref timeWorked)); WriteLine("-------------------------------------------------------"); WriteLine(" Overtime: {0:f} {1:f}", ts.CalculateOvertime(ref timeWorked), ts.CalculateOvertimePay(ref timeWorked)); WriteLine("======================================================="); WriteLine(" Net Pay: {0:f}", ts.CalculateGrossPay(ref timeWorked)); WriteLine("======================================================="); }
Enter the Id of the time sheet to view: I don't remember -------------------------------------------------------------- The number you provided for the time sheet to view is not valid. The error produced is: The input string 'I don't remember' was not in a correct format. ============================================================== Press any key to close this window . . .
Remember that a section of your code could end up throwing various exceptions or different types of exceptions. We saw that, to address such a situation, you can create a catch clause for each possibility. As an alternative, the C# language provides a keyword named when. The formula to use it is:
try
{
. . .
}
catch(exception-type) when (condition)
{
. . .
}
Once again, the compiler will first deal with the code in the try section. If there is a problem, then the compiler would move to the catch section. In that section, pass an exception-type, which is usually an Exception parameter or a class derived from Exception.
Filtering exceptions consists of specifying a criterion by which a particular exception, among others, would be selected. To proceed, after the closing parenthesis of the catch keyword, type the when (contextual) keyword. This keyword functions like an if conditional statement. This means that when must be followed by parentheses. In the parentheses of when(), create a logical expression (an expression that can evaluate to true or false). If that expression is true, in the body of the catch clause, create a consequential expression. This means that the body of the catch clause would execute if the when() conditional statement is true.
Practical Learning: Filtering an Exceptions
using PayrollPreparation6.Models;
using static System.Console;
PreparePayroll();
Employee Hire(in int number)
{
. . .
return new Employee();
}
TimeSheet GetTimeWorked(in int number)
{
. . .
return new TimeSheet(0, 0, 0, 0, 0, 0, 0);
}
void PreparePayroll()
{
try
{
Write("Enter the Id of the time sheet to view: ");
int nbr = int.Parse(ReadLine()!);
TimeSheet timeSheet = GetTimeWorked(nbr);
int emplNumber = timeSheet.GetEmployeeNumber();
Employee staff = Hire(emplNumber);
WriteLine("+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+");
WriteLine("FUN DEPARTMENT STORE");
WriteLine("=======================================================");
WriteLine("Payroll Evaluation");
WriteLine("=======================================================");
ShowEmployee(ref staff);
PresentPayroll(ref timeSheet);
}
catch (Exception exc) when (exc is FormatException fe)
{
WriteLine("--------------------------------------------------------------");
WriteLine("The number you provided for the time sheet to view is not valid.");
WriteLine("The error produced is: " + fe.Message);
WriteLine("==============================================================");
}
}
void ShowEmployee(ref readonly Employee empl)
{
. . .
}
void PresentPayroll(ref readonly TimeSheet ts)
{
. . .
}
Enter the Id of the time sheet to view: I don't know -------------------------------------------------------------- The number you provided for the time sheet to view is not valid. The error produced is: The input string 'I don't know' was not in a correct format. ============================================================== Press any key to close this window . . .
Filtering many Exceptions
Remember that a section of code can produce many errors. In other words, a section can produce various exceptions. As a result, you can create various catch sections, each with its when condition.
Practical Learning: Filtering many Exceptions
using static System.Console;
(int, int) DistributeParts(int amount, int portion1, int portion2)
{
int totalRatios = portion1 + portion2;
int eachPart = amount / totalRatios;
int result = eachPart * portion1;
return (result, amount - result);
}
int Subtract(int first, int second)
{
return first - second;
}
try
{
int amtPledged;
int ratio1;
int ratio2;
WriteLine("===================================================");
WriteLine("Pledge Distribution");
WriteLine("===================================================");
WriteLine("Type the values to evaluate a pledge distribution");
Write("Amount to Allocate: ");
amtPledged = int.Parse(ReadLine()!);
Write("Portion 1: ");
ratio1 = int.Parse(ReadLine()!);
Write("Portion 2: ");
ratio2 = int.Parse(ReadLine()!);
(int first, int second) portions = DistributeParts(amtPledged, ratio1, ratio2);
WriteLine("===================================================");
WriteLine("Pledge Distribution");
WriteLine("===================================================");
WriteLine($"Amouont Allocated: {amtPledged}");
WriteLine($"Portion 1: {ratio1}");
WriteLine($"Portion 2: {ratio2}");
WriteLine("---------------------------------------------------");
WriteLine($"Part 1: {portions.first}");
WriteLine($"Part 2: {portions.second}");
WriteLine("===================================================");
}
catch(Exception exc) when ( exc is FormatException fe)
{
WriteLine("---------------------------------------------------------------");
WriteLine("The value you entered for the amount to pledge " +
"(or to allocate) is not valid. ");
WriteLine("Please type a valid value (such as 200, 1250, 5000, or 100000).");
WriteLine("==============================================================");
WriteLine("The error produced is: " + fe.Message);
}
catch (Exception exc) when (exc is DivideByZeroException dze)
{
WriteLine("---------------------------------------------------------------");
WriteLine("It appears that you entered 0 for the ratio(s), which is not allowed.");
WriteLine("The error produced is: " + dze.Message);
WriteLine("==============================================================");
}
=================================================== Pledge Distribution =================================================== Type the values to evaluate a pledge distribution Amount to Allocate: I pledge 10,000 dollars --------------------------------------------------------------- The value you entered for the amount to pledge (or to allocate) is not valid. Please type a valid value (such as 200, 1250, 5000, or 100000). ============================================================== The error produced is: The input string 'I pledge 10,000 dollars' was not in a correct format. Press any key to close this window . . .
=================================================== Pledge Distribution =================================================== Type the values to evaluate a pledge distribution Amount to Allocate: 10000 Portion 1: Six --------------------------------------------------------------- The value you entered for the amount to pledge (or to allocate) is not valid. Please type a valid value (such as 200, 1250, 5000, or 100000). ============================================================== The error produced is: The input string 'Six' was not in a correct format. Press any key to close this window . . .
=================================================== Pledge Distribution =================================================== Type the values to evaluate a pledge distribution Amount to Allocate: 10000 Portion 1: 0 Portion 2: 0 --------------------------------------------------------------- It appears that you entered 0 for the ratio(s), which is not allowed. The error produced is: Attempted to divide by zero. ============================================================== Press any key to close this window . . .
Introduction
As mentioned previously, the Exception class is equipped with a Message property that carries a message for the error that occurred. We also mentioned that the message of this property may not be particularly useful to a user. Fortunately, you can create your own message and pass it to an Exception object. To be able to receive custom messages, the Exception class provides the following constructor:
public Exception(string message);
As mentioned already, all exceptions classes derive directly or indirectly from Exception. As a result, all those classes are equipped with a default constructor and all of them inherit the constructor that takes a string as argument.
To use the constructor that uses a string parameter, in the section in which you are anticipating the error, use a keyword named throw. Follow this keyword by the new operator to instantiate the Exception class using this constructor. Here is an example:
using static System.Console;
try
{
double result = 0.00;
string oper = "";
double number1 = 0.00, number2 = 0.00;
Write("Number 1: ");
number1 = double.Parse(ReadLine()!);
Write("Operator: ");
oper = ReadLine()!;
Write("Number 2: ");
number2 = double.Parse(ReadLine()!);
if ((oper != "+") && (oper != "-") && (oper != "*") && (oper != "/"))
{
throw new Exception(oper);
}
switch (oper)
{
case "+":
result = number1 + number2;
break;
case "-":
result = number1 - number2;
break;
case "*":
result = number1 * number2;
break;
case "/":
result = number1 / number2;
break;
default:
WriteLine("Bad Operation");
break;
}
WriteLine("-------------------------");
WriteLine("{0} {1} {2} = {3}", number1, oper, number2, result);
}
catch (Exception exc)
{
WriteLine("A value or operator you entered is not valid.");
}
WriteLine("================================");
Here is an example of running the application:
Number 1: 837 Operator: + Number 2: 559 ------------------------- 837 + 559 = 1396 ================================ Press any key to close this window . . .
Exceptions and Methods
There are various ways you can involve exceptions in a function or method. When it comes to functions and methods, one way you can use the throw option is to get out of the function or method at any time, for any reason. Consider the following code:
class Exercise
{
public void ShowMessage()
{
throw new Exception();
WriteLine("This is the wonderful world of C# programming.");
}
}
In this example, the line that holds the message box will never be reached. One way you can proceed in a function or method is to throw an exception if something happens. That is, you can create a conditional statement that would consider, or throw an exception.
Practical Learning: Throwing an Exception from a Method
using static System.Console;
(int, int) DistributeParts(int amount, int portion1, int portion2)
{
int totalRatios = portion1 + portion2;
if (totalRatios == 0)
throw new FormatException("The value provided for one or both ratios is not valid.");
int eachPart = amount / totalRatios;
int result = eachPart * portion1;
return (result, amount - result);
}
int Subtract(int first, int second)
{
return first - second;
}
try
{
int amtPledged;
int ratio1;
int ratio2;
WriteLine("===================================================");
WriteLine("Pledge Distribution");
WriteLine("===================================================");
WriteLine("Type the values to evaluate a pledge distribution");
Write("Amount to Allocate: ");
amtPledged = int.Parse(ReadLine()!);
Write("Portion 1: ");
ratio1 = int.Parse(ReadLine()!);
Write("Portion 2: ");
ratio2 = int.Parse(ReadLine()!);
(int first, int second) portions = DistributeParts(amtPledged, ratio1, ratio2);
WriteLine("===================================================");
WriteLine("Pledge Distribution");
WriteLine("===================================================");
WriteLine($"Amouont Allocated: {amtPledged}");
WriteLine($"Portion 1: {ratio1}");
WriteLine($"Portion 2: {ratio2}");
WriteLine("---------------------------------------------------");
WriteLine($"Part 1: {portions.first}");
WriteLine($"Part 2: {portions.second}");
WriteLine("===================================================");
}
catch (FormatException)
{
WriteLine("The value you entered for the amount to allocate " +
"or pledge is not valid. Only natural numbers " +
"(such as 200, 1250, 5000, or 100000) are allowed.");
}
=================================================== Pledge Distribution =================================================== Type the values to evaluate a pledge distribution Amount to Allocate: 8500 Portion 1: 0 Portion 2: 0 The value you entered for the amount to allocate or pledge is not valid. Only natural numbers (such as 200, 1250, 5000, or 100000) are allowed. Press any key to close this window . . .
using static System.Console; int DistributeFirstPart(int amount, int portion1, int portion2) { if (portion1 != 0) { int totalRatios = portion1 + portion2; int eachPart = amount / totalRatios; int result = eachPart * portion1; return result; } else throw new FormatException("The value provided for the first ratio portion is not valid."); } int Subtract(int first, int second) { if (first == 0) throw new FormatException("The value provided for the amount to pledge must be a positive number."); return first - second; } try { int amtPledged; int ratio1; int ratio2; WriteLine("==================================================="); WriteLine("Pledge Distribution"); WriteLine("==================================================="); WriteLine("Type the values to evaluate a pledge distribution"); Write("Amount to Allocate: "); amtPledged = int.Parse(ReadLine()!); Write("Portion 1: "); ratio1 = int.Parse(ReadLine()!); Write("Portion 2: "); ratio2 = int.Parse(ReadLine()!); int part1 = DistributeFirstPart(amtPledged, ratio1, ratio2); int part2 = Subtract(amtPledged, part1); WriteLine("==================================================="); WriteLine("Pledge Distribution"); WriteLine("==================================================="); WriteLine($"Amouont Allocated: {amtPledged}"); WriteLine($"Portion 1: {ratio1}"); WriteLine($"Portion 2: {ratio2}"); WriteLine("---------------------------------------------------"); WriteLine($"Part 1: {part1}"); WriteLine($"Part 2: {part2}"); WriteLine("==================================================="); } catch (FormatException) { WriteLine("The value you entered for the amount to allocate " + "or pledge is not valid. Only natural numbers " + "(such as 200, 1250, 5000, or 100000) are allowed."); }
=================================================== Pledge Distribution =================================================== Type the values to evaluate a pledge distribution Amount to Allocate: 5000 Portion 1: 0 Portion 2: 0 The value you entered for the amount to allocate or pledge is not valid. Only natural numbers (such as 200, 1250, 5000, or 100000) are allowed. Press any key to close this window . . .
Exceptions and Properties
If you create a non-automatic property that processes some data and returns a valid result, if there is a possibility that something could go wrong in the calculation, you can make the property throw an exception. You can perform some procesing in the set clause of the property. In that clause, you can throw an exception. Here is an example:
public class WorkDay
{
private double tw;
public WorkDay(double time)
{
tw = time;
}
public double TimeWorked
{
get
{
return tw;
}
set
{
if (tw > 24)
throw new FormatException("Nobody can work more than 24 hours in one day.");
tw = value;
}
}
}
Or you can handle the exception in the get clause.
Nesting an Exception
You can create an exception inside of another. This is referred to as nesting an exception. This is done by applying the same techniques we used to nest conditional statements. This means that you can write an exception that depends on, and is subject to, another exception. To nest an exception, write a try block in the body of the parent exception. The nested try block must be followed by its own catch clause(s). To effectively handle the exception(s), make sure you include an appropriate throw in the try block.
Here is an example:
using static System.Console; try { double result = 0.00; string oper = ""; double number1 = 0.00, number2 = 0.00; Write("Number 1: "); number1 = double.Parse(ReadLine()!); Write("Operator: "); oper = ReadLine()!; Write("Number 2: "); number2 = double.Parse(ReadLine()!); if ((oper != "+") && (oper != "-") && (oper != "*") && (oper != "/")) { throw new Exception(oper); } switch (oper) { case "+": result = number1 + number2; break; case "-": result = number1 - number2; break; case "*": result = number1 * number2; break; case "/": try { if (number2 == 0) throw new DivideByZeroException("Division by zero is not allowed"); result = number1 / number2; } catch (DivideByZeroException ex) { WriteLine(ex.Message); } break; default: WriteLine("Bad Operation"); break; } WriteLine("-----------------------------------"); WriteLine("{0} {1} {2} = {3}", number1, oper, number2, result); } catch (FormatException) { WriteLine("You type an invalid number. Please correct it"); } catch (Exception ex) { WriteLine("Operation Error: " + ex.Message + " is not a valid operator"); } WriteLine("===================================");
Here is an example of running the application:
Number 1: 9284259 Operator: / Number 2: 731 ----------------------------------- 9284259 / 731 = 12700.764705882353 =================================== Press any key to close this window . . .
Practical Learning: Handling Exceptions
namespace StellarWaterPoint3 { internal enum Classification { Residential, NonProfit, WaterIntensive, GeneralUse, Other } internal class WaterBill { private readonly string typeOfAccount; public WaterBill(string category) => typeOfAccount = category; public double CounterReadingStart { get; set; } public double CounterReadingEnd { get; set; } public (Classification @class, string name) AccountType { get { if (typeOfAccount == "1") return (Classification.Residential, "Residential Household"); else if (typeOfAccount == "2") return (Classification.NonProfit, "Social/Non-Profit Organization"); else if (typeOfAccount == "3") return (Classification.WaterIntensive, "Water Intensive Business (Laudromat, Hair Salon, etc)"); else if (typeOfAccount == "4") return (Classification.GeneralUse, "General Business, Government"); else return (Classification.Other, "Other"); } } public double Gallons => CounterReadingEnd - CounterReadingStart; public double HCFTotal => Gallons / 748; public (double First25Therms, double Next15Therms, double Above40Therms) Therms { get { double first, next, above; if (HCFTotal is > 40.00) { first = 25.00 * 1.5573; next = 15.00 * 1.2264; above = (HCFTotal - 40.00) * 0.9624; } else if (HCFTotal > 25.00) { first = 25.00 * 1.5573; next = (HCFTotal - 25.00) * 1.2264; above = 0.00; } else // if (HCFTotal > 40.00) { first = HCFTotal * 1.5573; next = 0.00; above = 0.00; } return (first, next, above); } } public double WaterUsageCharges => Therms.First25Therms + Therms.Next15Therms + Therms.Above40Therms; public double SewerCharges { get { double result = AccountType.@class switch { Classification.Residential => WaterUsageCharges * 0.2528, Classification.NonProfit => WaterUsageCharges * 0.0915, Classification.WaterIntensive => WaterUsageCharges * 1.5865, Classification.GeneralUse => WaterUsageCharges * 0.6405, _ => WaterUsageCharges * 1.2125 }; return result; } } public double EnvironmentCharges { get { double result = AccountType.@class switch { Classification.Residential => WaterUsageCharges * 0.0025, Classification.NonProfit => WaterUsageCharges * 0.0015, Classification.WaterIntensive => WaterUsageCharges * 0.0105, Classification.GeneralUse => WaterUsageCharges * 0.0045, _ => WaterUsageCharges * 0.0125 }; return result; } } public double ServiceCharges { get => AccountType.@class switch { Classification.Residential => WaterUsageCharges * 0.0328, Classification.NonProfit => WaterUsageCharges * 0.0115, Classification.WaterIntensive => WaterUsageCharges * 0.1015, Classification.GeneralUse => WaterUsageCharges * 0.0808, _ => WaterUsageCharges * 0.1164 }; } public double TotalCharges => WaterUsageCharges + SewerCharges + EnvironmentCharges + ServiceCharges; public double LocalTaxes { get => AccountType.@class switch { Classification.Residential => TotalCharges * 0.115, Classification.NonProfit => TotalCharges * 0.085, Classification.WaterIntensive => TotalCharges * 0.825, Classification.GeneralUse => TotalCharges * 0.315, _ => TotalCharges * 0.625 }; } public double StateTaxes => AccountType.@class switch { Classification.Residential => TotalCharges * 0.035, Classification.NonProfit => TotalCharges * 0.015, Classification.WaterIntensive => TotalCharges * 0.105, Classification.GeneralUse => TotalCharges * 0.065, _ => TotalCharges * 0.815 }; public double AmountDue => TotalCharges + LocalTaxes + StateTaxes; } }
using StellarWaterPoint3; using static System.Console; WriteLine("Stellar Water Point"); WriteLine("==========================================================="); string ? answer = ""; WaterBill ? bill; try { WriteLine("To prepare an invoice, enter the following information"); WriteLine("Types of Accounts"); WriteLine("1. Residential Household"); WriteLine("2. Social/Non-Profit Organization"); WriteLine("3. Water Intensive Business (Laudromat, etc)"); WriteLine("4. General Business"); WriteLine("0. Other"); Write("Enter Type of Account: "); answer = ReadLine()!; WriteLine("-----------------------------------------------------------"); } catch(FormatException fe) { WriteLine("There was an error from the request for the account type was presented." + Environment.NewLine + "The error produced was: " + fe.Message); WriteLine("-----------------------------------------------------------"); } bill = new WaterBill(answer); try { Write("Counter Reading Start: "); bill.CounterReadingStart = int.Parse(ReadLine()!); } catch (FormatException fe) { WriteLine("There was an error from the request for the counter starting number was made." + Environment.NewLine + "The error produced was: " + fe.Message); WriteLine("-----------------------------------------------------------"); } try { Write("Counter Reading End: "); bill.CounterReadingEnd = int.Parse(ReadLine()!); } catch (FormatException fe) { WriteLine("There was an error from the request for the counter ending number was made." + Environment.NewLine + "The error produced was: " + fe.Message); WriteLine("-----------------------------------------------------------"); } if( (answer != "") && (bill.CounterReadingStart != 0) && (bill.CounterReadingEnd != 0)) { WriteLine("==========================================================="); WriteLine("Stellar Water Point - Customer Invoice"); WriteLine("Account Type: {0}", bill.AccountType.name); WriteLine("==========================================================="); WriteLine("Meter Reading"); WriteLine("-----------------------------------------------------------"); WriteLine("Counter Reading Start: {0,10}", bill.CounterReadingStart); WriteLine("Counter Reading End: {0,10}", bill.CounterReadingEnd); WriteLine("Total Gallons Consumed: {0,10}", bill.Gallons); WriteLine("==========================================================="); WriteLine("Therms Evaluation"); WriteLine("-----------------------------------------------------------"); WriteLine("HCF Total: {0,10:n}", bill.HCFTotal); WriteLine("First 35 Therms (* 1.5573): {0,10:n}", bill.Therms.First25Therms); WriteLine("First 20 Therms (* 1.2264): {0,10:n}", bill.Therms.Next15Therms); WriteLine("Above 40 Therms (* 0.9624): {0,10:n}", bill.Therms.Above40Therms); WriteLine("-----------------------------------------------------------"); WriteLine("Water Usage Charges: {0,10:n}", bill.WaterUsageCharges); WriteLine("Sewer Charges: {0,10:n}", bill.SewerCharges); WriteLine("==========================================================="); WriteLine("Bill Values"); WriteLine("-----------------------------------------------------------"); WriteLine("Environment Charges: {0,10:n}", bill.EnvironmentCharges); WriteLine("Service Charges: {0,10:n}", bill.ServiceCharges); WriteLine("Total Charges: {0,10:n}", bill.TotalCharges); WriteLine("Local Taxes: {0,10:n}", bill.LocalTaxes); WriteLine("State Taxes: {0,10:n}", bill.StateTaxes); WriteLine("-----------------------------------------------------------"); WriteLine("Amount Due: {0,10:n}", bill.AmountDue); } else { Write("==========================================================="); WriteLine("The water bill was not prepared appropriately."); } Write("===========================================================");
Stellar Water Point =========================================================== To prepare an invoice, enter the following information Types of Accounts 1. Residential Household 2. Social/Non-Profit Organization 3. Water Intensive Business (Laudromat, etc) 4. General Business 0. Other Enter Type of Account: ----------------------------------------------------------- Counter Reading Start: 26526 Counter Reading End: 42528 =========================================================== The water bill was not prepared appropriately. =========================================================== Press any key to close this window . . .
Stellar Water Point =========================================================== To prepare an invoice, enter the following information Types of Accounts 1. Residential Household 2. Social/Non-Profit Organization 3. Water Intensive Business (Laudromat, etc) 4. General Business 0. Other Enter Type of Account: 1 ----------------------------------------------------------- Counter Reading Start: w There was an error from the request for the counter starting number was made. The error produced was: Input string was not in a correct format. ----------------------------------------------------------- Counter Reading End: 42528 =========================================================== The water bill was not prepared appropriately. =========================================================== Press any key to close this window . . .
Stellar Water Point =========================================================== To prepare an invoice, enter the following information Types of Accounts 1. Residential Household 2. Social/Non-Profit Organization 3. Water Intensive Business (Laudromat, etc) 4. General Business 0. Other Enter Type of Account: 1 ----------------------------------------------------------- Counter Reading Start: w There was an error from the request for the counter starting number was made. The error produced was: Input string was not in a correct format. ----------------------------------------------------------- Counter Reading End: a There was an error from the request for the counter ending number was made. The error produced was: Input string was not in a correct format. ----------------------------------------------------------- =========================================================== The water bill was not prepared appropriately. =========================================================== Press any key to close this window . . .
Stellar Water Point =========================================================== To prepare an invoice, enter the following information Types of Accounts 1. Residential Household 2. Social/Non-Profit Organization 3. Water Intensive Business (Laudromat, etc) 4. General Business 0. Other Enter Type of Account: 1 ----------------------------------------------------------- Counter Reading Start: 41722 Counter Reading End: 88061 =========================================================== Stellar Water Point - Customer Invoice Account Type: Residential Household =========================================================== Meter Reading ----------------------------------------------------------- Counter Reading Start: 41722 Counter Reading End: 88061 Total Gallons Consumed: 46339 =========================================================== Therms Evaluation ----------------------------------------------------------- HCF Total: 61.95 First 35 Therms (* 1.5573): 38.93 First 20 Therms (* 1.2264): 18.40 Above 40 Therms (* 0.9624): 21.13 ----------------------------------------------------------- Water Usage Charges: 78.45 Sewer Charges: 19.83 =========================================================== Bill Values ----------------------------------------------------------- Environment Charges: 0.20 Service Charges: 2.57 Total Charges: 101.06 Local Taxes: 11.62 State Taxes: 3.54 ----------------------------------------------------------- Amount Due: 116.21 =========================================================== Press any key to close this window . . .
|
|||
Previous | Copyright © 2001-2024, FunctionX | Sunday 05 November 2021 | Next |
|