|
C# Errors & Exceptions: Introduction to Exception
Handling |
|
Introduction to Exceptions |
|
|
During the execution of a program, the computer will
face two types of situations: those it is prepared to deal with and those it
is not. Imagine you write a program that requests a number from the user:
|
using System;
class Program
{
static int Main()
{
double side;
Console.WriteLine("Square Processing");
Console.Write("Enter Side: ");
side = double.Parse(Console.ReadLine());
Console.WriteLine("\nSquare Characteristics");
Console.WriteLine("Side: {0}", side);
Console.WriteLine("Perimeter: {0}", side * 4);
return 0;
}
}
This is a classic easy program. When it comes up, the
user is asked to simply type a number. The number would then be multiplied
by 4 and the result is displayed. Imagine that a user types something that
is not a valid number, such as the name of a country or somebody's telephone
number. Since this program was expecting a number and it is not prepared to
multiply a string to a number, it would not know what to do. The only
alternative the compiler would have is to send the problem to the operating
system, hoping that the OS would know what to do. What actually happens is
that, whenever the compiler is handed a task, it would try to perform the
assignment. If it cannot perform the assignment, for any reason it is not
prepared for, it would produce an error. As a programmer, if you can
anticipate the type of error that could occur in your program, you can
identify the error yourself and deal with it by telling the compiler what to
do when an error occurs.
Application:
Introducing Exception Handling
|
|
- Start Microsoft Visual Studio
- To create a new application, on the main menu, click File -> New
Project...
- In the middle list, click Empty Project
- Set the name to GeorgetownDryCleaningServices5
- Click OK
- To create a new class, in the Solution Explorer, right-click
GeorgetownDryCleaningServices5 -> Add -> Class...
- Set the Name to CleaningOrderInfo and click OK
- Change the file as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace GeorgetownDryCleaningServices5
{
public class CleaningOrderInfo
{
// Basic information about an order
public string CustomerName;
public string HomePhone;
public DateTime OrderDate;
public DateTime OrderTime;
// Unsigned numbers to represent cleaning items
public uint numberOfShirts;
public uint numberOfPants;
public uint NumberOfDresses;
}
}
- To create a new class, on the main menu, click Project -> Add
Class...
- Set the Name to OrderProcessing and press Enter
- Change the file as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace GeorgetownDryCleaningServices5
{
public class sealed OrderProcessing
{
#region Objects used to process an order
// Price of items
const decimal priceOneShirt = 0.95M;
const decimal priceAPairOfPants = 2.95M;
const decimal PriceOneDress = 4.55M;
const decimal TaxRate = 0.0575M; // 5.75%
CleaningOrderInfo cleaningOrder;
// Each of these sub totals will be used for cleaning items
private decimal SubTotalShirts;
private decimal SubTotalPants;
private decimal SubTotalDresses;
// Values used to process an order
private decimal TotalOrder;
private decimal TaxAmount;
private decimal SalesTotal;
private decimal AmountTended;
private decimal Difference;
#endregion
#region Actions used to process and present an order
public OrderProcessing()
{
cleaningOrder = new CleaningOrderInfo();
}
public void ProcessOrder()
{
Console.WriteLine("-/- Georgetown Cleaning Services -/-");
// Request order information from the user
Console.Write("Enter Customer Name: ");
cleaningOrder.CustomerName = Console.ReadLine();
Console.Write("Enter Customer Phone: ");
cleaningOrder.HomePhone = Console.ReadLine();
Console.Write("Enter the order date(mm/dd/yyyy): ");
cleaningOrder.OrderDate = DateTime.Parse(Console.ReadLine());
Console.Write("Enter the order time(hh:mm AM/PM): ");
cleaningOrder.OrderTime = DateTime.Parse(Console.ReadLine());
// Request the quantity of each category of items
Console.Write("Number of Shirts: ");
cleaningOrder.numberOfShirts = uint.Parse(Console.ReadLine());
Console.Write("Number of Pants: ");
cleaningOrder.numberOfPants = uint.Parse(Console.ReadLine());
Console.Write("Number of Dresses: ");
cleaningOrder.NumberOfDresses = uint.Parse(Console.ReadLine());
// Perform the necessary calculations
SubTotalShirts = cleaningOrder.numberOfShirts * priceOneShirt;
SubTotalPants = cleaningOrder.numberOfPants * priceAPairOfPants;
SubTotalDresses = cleaningOrder.NumberOfDresses * PriceOneDress;
// Calculate the "temporary" total of the order
TotalOrder = SubTotalShirts + SubTotalPants + SubTotalDresses;
// Calculate the tax amount using a constant rate
TaxAmount = TotalOrder * TaxRate;
// Add the tax amount to the total order
SalesTotal = TotalOrder + TaxAmount;
// Communicate the total to the user...
Console.WriteLine("\nThe Total order is: {0:C}", SalesTotal);
// and request money for the order
Console.Write("Amount Tended? ");
AmountTended = decimal.Parse(Console.ReadLine());
// Calculate the difference owed to the customer
// or that the customer still owes to the store
Difference = AmountTended - SalesTotal;
ShowReceipt();
}
private void ShowReceipt()
{
// Display the receipt
Console.WriteLine("====================================");
Console.WriteLine("-/- Georgetown Cleaning Services -/-");
Console.WriteLine("====================================");
Console.WriteLine("Customer: {0}", cleaningOrder.CustomerName);
Console.WriteLine("Home Phone: {0}", cleaningOrder.HomePhone);
Console.WriteLine("Order Date: {0:D}", cleaningOrder.OrderDate);
Console.WriteLine("Order Time: {0:t}", cleaningOrder.OrderTime);
Console.WriteLine("------------------------------------");
Console.WriteLine("Item Type Qty Unit/Price Sub-Total");
Console.WriteLine("------------------------------------");
Console.WriteLine("Shirts {0,3} {1,4} {2,6}",
cleaningOrder.numberOfShirts, priceOneShirt, SubTotalShirts);
Console.WriteLine("Pants {0,3} {1,4} {2,6}",
cleaningOrder.numberOfPants, priceAPairOfPants, SubTotalPants);
Console.WriteLine("Dresses {0,3} {1,4} {2,6}",
cleaningOrder.NumberOfDresses, PriceOneDress, SubTotalDresses);
Console.WriteLine("------------------------------------");
Console.WriteLine("Total Order: {0,6}", TotalOrder.ToString("C"));
Console.WriteLine("Tax Rate: {0,6}", TaxRate.ToString("P"));
Console.WriteLine("Tax Amount: {0,6}", TaxAmount.ToString("C"));
Console.WriteLine("Net Price: {0,6}", SalesTotal.ToString("C"));
Console.WriteLine("------------------------------------");
Console.WriteLine("Amount Tended: {0,6}",
AmountTended.ToString("C"));
Console.WriteLine("Difference: {0,6}", Difference.ToString("C"));
Console.WriteLine("====================================");
}
#endregion
}
}
- To create a new file, on the main menu, click Project -> Add New
Item...
- In the middle list, click Code File
- Change the Name to ClearningOrder and press Enter
- Type the following:
using System;
using GeorgetownDryCleaningServices5
public class CustomerOrder
{
public static int Main()
{
OrderProcessing Order = new OrderProcessing();
Console.Clear();
Order.ProcessOrder();
System.Console.ReadKey();
return 0;
}
}
- To test the application, on the main menu, click Debug -> Start
Debugging
- Enter the values as follows (press Enter after each):
-/- Georgetown Cleaning Services -/-
Enter Customer Name: Peter Moonstruck
Enter Customer Phone: (301) 728-8830
Enter the order date(mm/dd/yyyy): 04/22/2006
Enter the order time(hh:mm AM/PM): 08:46
Number of Shirts: 5
Number of Pants: 2
Number of Dresses: 3
The Total order is: $25.70
Amount Tended? 30
- Press Enter:
====================================
-/- Georgetown Cleaning Services -/-
====================================
Customer: Peter Moonstruck
Home Phone: (301) 728-8830
Order Date: Saturday, April 22, 2006
Order Time: 8:46 AM
------------------------------------
Item Type Qty Unit/Price Sub-Total
------------------------------------
Shirts 5 0.95 4.75
Pants 2 2.95 5.90
Dresses 3 4.55 13.65
------------------------------------
Total Order: $24.30
Tax Rate: 5.75 %
Tax Amount: $1.40
Net Price: $25.70
------------------------------------
Amount Tended: $30.00
Difference: $4.30
====================================
- Close the DOS window
An exception is an unusual situation that could occur in
your program. As a programmer, you should anticipate any abnormal behavior
that could be caused by the user entering wrong information that could
otherwise lead to unpredictable results. The ability to deal with a
program's eventual abnormal behavior is called exception handling. C#
provides three keywords to handle an exception.
- Trying the normal flow: To deal with the expected behavior of
a program, use the try keyword as in the following syntax:
try {Behavior}
The try keyword is
required. It lets the compiler know that you are attempting a normal
flow of the program. The actual behavior that needs to be evaluated is
included between an opening curly bracket
“{“ and a closing curly bracket
“}â€Â. Inside of the brackets, implement the
normal flow that the program must follow, at least for this section of
the code. Here is an example:
using System;
class Program
{
static int Main()
{
double side;
Console.WriteLine("Square Processing");
try
{
Console.Write("Enter Side: ");
side = double.Parse(Console.ReadLine());
Console.WriteLine("\nSquare Characteristics");
Console.WriteLine("Side: {0}", side);
Console.WriteLine("Perimeter: {0}", side * 4);
}
return 0;
}
}
- Catching Errors: During the flow of the program as part of
the try section, if an abnormal behavior occurs, instead of
letting the program crash or instead of letting the compiler send the
error to the operating system, you can transfer the flow of the program
to another section that can deal with it. The syntax used by this
section is:
catch {WhatToDo}
This section always follows the try section. There must not be
any code between the try’s closing bracket and
the catch section. The catch keyword is required and
follows the try section. Combined with the try block, the syntax
of an exception would be:
try
{
// Try the program flow
}
catch
{
// Catch the exception
}
A program that includes a catch section would appear as follows:
using System;
public class Exercise
{
static int Main()
{
double Number;
try
{
Console.Write("Type a number: ");
Number = double.Parse(Console.ReadLine());
Console.WriteLine("\n{0} * 2 = {1}", Number, Number * 2);
}
catch
{
}
return 0;
}
}
Application:
Introducing Vague Exceptions
|
|
- To introduce exceptions, access the OrderProcessing.cs file and
change it as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace GeorgetownDryCleaningServices5
{
class OrderProcessing
{
. . . No Change
public void ProcessOrder()
{
. . . No Change
// Request the quantity of each category of items
try
{
Console.Write("Number of Shirts: ");
Order.numberOfShirts = uint.Parse(Console.ReadLine());
}
catch
{
}
try
{
Console.Write("Number of Pants: ");
Order.numberOfPants = uint.Parse(Console.ReadLine());
}
catch
{
}
try
{
Console.Write("Number of Dresses: ");
Order.NumberOfDresses = uint.Parse(Console.ReadLine());
}
catch
{
}
. . . No Change
// and request money for the order
try
{
Console.Write("Amount Tended? ");
AmountTended = decimal.Parse(Console.ReadLine());
}
catch
{
}
// Calculate the difference owed to the customer
// or that the customer still owes to the store
Difference = AmountTended - SalesTotal;
ShowReceipt();
}
private void ShowReceipt()
{
. . . No Change
}
}
}
- Execute the application to test it
- Close the DOS window
Exceptions and Custom Messages
|
|
As mentioned already, if an error occurs when processing
the program in the try section, the compiler transfers the processing to the
next catch section. You can then use the catch section to deal with the
error. At a minimum, you can display a message to inform the user. Here is
an example:
using System;
class Program
{
static int Main()
{
double side;
Console.WriteLine("Square Processing");
try
{
Console.Write("Enter Side: ");
side = double.Parse(Console.ReadLine());
Console.WriteLine("\nSquare Characteristics");
Console.WriteLine("Side: {0}", side);
Console.WriteLine("Perimeter: {0}", side * 4);
}
catch
{
Console.WriteLine("There was a problem with the program");
}
return 0;
}
}
Here is an error of running the program:
Square Processing
Enter Side: w4
There was a problem with the program
Press any key to continue . . .
Of course, this type of message is not particularly
clear but this time, the program will not crash. In the next sections, we
will learn better ways of dealing with the errors and the messages.
Application:
Displaying Custom Messages
|
|
- To display custom messages to the user, change the
OrderProcessing.cs file as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace GeorgetownDryCleaningServices5
{
class OrderProcessing
{
. . . No Change
public void ProcessOrder()
{
. . . No Change
// Request the quantity of each category of items
try
{
Console.Write("Number of Shirts: ");
Order.numberOfShirts = uint.Parse(Console.ReadLine());
}
catch
{
Console.WriteLine("The value you typed for the number of " +
"shirts is not a valid number");
}
try
{
Console.Write("Number of Pants: ");
Order.numberOfPants = uint.Parse(Console.ReadLine());
}
catch
{
Console.WriteLine("The value you typed for the number of " +
"pair or pants is not a valid number");
}
try
{
Console.Write("Number of Dresses: ");
Order.NumberOfDresses = uint.Parse(Console.ReadLine());
}
catch
{
Console.WriteLine("The value you typed for the number of " +
"dresses is not a valid number");
}
. . . No Change
try
{
Console.Write("Amount Tended? ");
AmountTended = decimal.Parse(Console.ReadLine());
}
catch
{
Console.WriteLine(
"You were asked to enter an amount of money but...");
}
// Calculate the difference owed to the customer
// or that the customer still owes to the store
Difference = AmountTended - SalesTotal;
ShowReceipt();
}
private void ShowReceipt()
{
. . . No Change
}
}
}
- Execute the application to test it. Here is an example:
-/- Georgetown Cleaning Services -/-
Enter Customer Name: Alexandria
Enter Customer Phone: (102) 797-8382
Enter the order date(mm/dd/yyyy): 04/02/2001
Enter the order time(hh:mm AM/PM): 09:22 AM
Number of Shirts: 6
Number of Pants: W
The value you typed for the number of pair or pants is not a valid number
Number of Dresses: 5
The Total order is: $30.09
Amount Tended? _100D
You were asked to enter an amount of money but...
- Press Enter:
====================================
-/- Georgetown Cleaning Services -/-
====================================
Customer: Alexandria
Home Phone: (102) 797-8382
Order Date: Monday, April 02, 2001
Order Time: 9:22 AM
------------------------------------
Item Type Qty Unit/Price Sub-Total
------------------------------------
Shirts 6 0.95 5.70
Pants 0 2.95 0
Dresses 5 4.55 22.75
------------------------------------
Total Order: $28.45
Tax Rate: 5.75 %
Tax Amount: $1.64
Net Price: $30.09
------------------------------------
Amount Tended: $0.00
Difference: ($30.09)
====================================
- Close the DOS window
Exceptions in the .NET Framework
|
|
In traditionally-oriented error dealing languages such
as C/C++, Object Pascal, or Visual Basic, you could create any exception of
your choice, including numeric or strings. To customize exception handling,
you could also create your own class(es). Most libraries such as Borland's
VCL and Microsoft's MFC also shipped with their own classes to handle
exceptions. Even the Win32 library provides its type of mechanism to face
errors. To support exception handling, the .NET Framework provides a special
class called Exception. Once the compiler encounters an error, the
Exception class allows you to identify the type of error and take an
appropriate action.
Normally, Exception mostly serves as the general
class of exceptions. Anticipating various types of problems that can occur
in a program, Microsoft derived various classes from Exception to
make this issue friendlier. As a result, almost any type of exception you
may encounter already has a class created to deal with it. Therefore, when
your program faces an exception, you can easily identify the type of error.
There are so many exception classes that we cannot study or review them all.
The solution we will use is to introduce or review a class when we meet its
type of error.
In exception handling, errors are dealt with in the
catch section. To do this, use catch as if it were a method. This means
that, on the right side of catch, open a parenthesis, declare a
variable of the type of exception you want to deal with. By default, an
exception is first of type Exception. Based on this, a typical
formula to implement exception handling is:
try
{
// Process the normal flow of the program here
}
catch(Exception e)
{
// Deal with the exception here
}
When an exception occurs in the try section, code
compilation is transferred to the catch section. If you declare the
exception as an Exception type, this class will identify the error.
One of the properties of the Exception class is called Message.
This property contains a string that describes the type of error that
occurred. You can then access this Exception.Message property to
display an error message if you want. Here is an example:
using System;
class Program
{
static int Main()
{
double side;
Console.WriteLine("Square Processing");
try
{
Console.Write("Enter Side: ");
side = double.Parse(Console.ReadLine());
Console.WriteLine("\nSquare Characteristics");
Console.WriteLine("Side: {0}", side);
Console.WriteLine("Perimeter: {0}", side * 4);
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
return 0;
}
}
Here is an example of running the program:
Square Processing
Enter Side: Wer24
Input string was not in a correct format.
Press any key to continue . . .
As you can see, one of the strengths of the
Exception.Message property is that it gives you a good indication of the
type of problem that occurred. Sometimes, the message provided by the
Exception class may not appear explicit enough. In fact, you may not
want to show it to the user since, as in this case, the user may not
understand what the expression "correct format" in this context means and
why it is being used. As an alternative, you can create your own message and
display it to the user. Here is an example:
using System;
class Program
{
static int Main()
{
double side;
Console.WriteLine("Square Processing");
try
{
Console.Write("Enter Side: ");
side = double.Parse(Console.ReadLine());
Console.WriteLine("\nSquare Characteristics");
Console.WriteLine("Side: {0}", side);
Console.WriteLine("Perimeter: {0}", side * 4);
}
catch(Exception ex)
{
Console.WriteLine("The operation could not be carried because " +
"the number you typed is not valid");
}
return 0;
}
}
Here is an example of running the program:
Square Processing
Enter Side: 24.Gh
The operation could not be carried because the number you typed is not valid
Press any key to continue . . .
You can also combine the Exception.Message
message and your own message:
using System;
class Program
{
static int Main()
{
double side;
Console.WriteLine("Square Processing");
try
{
Console.Write("Enter Side: ");
side = double.Parse(Console.ReadLine());
Console.WriteLine("\nSquare Characteristics");
Console.WriteLine("Side: {0}", side);
Console.WriteLine("Perimeter: {0}", side * 4);
}
catch(Exception ex)
{
Console.Write(ex.Message);
Console.WriteLine(
" Consequently, The operation could not be carried because " +
"the number you typed is not valid");
}
return 0;
}
}
Here is an example of running the program:
Square Processing
Enter Side: 25.KL48
Input string was not in a correct format.. Consequently, The operation could not
be carried because the number you typed is not valid
Press any key to continue . . .
A Review of .NET Exception Classes
|
|
The .NET Framework provides various classes to handle
almost any type of exception you can think of. There are so many of these
classes that we can only mention the few that we regularly use in our
application.
There are two main ways you can use one of the classes
of the .NET Framework. If you know for sure that a particular exception will
be produced, pass its name to the catch() clause. You don't have to
name the argument. Then, in the catch() section, display a custom
message. The second option you have consists of using the throw
keyword. We will study it later.
From now on, we will try to always indicate the type of
exception that could be thrown if something goes wrong in a program
The FormatException Exception
|
|
When studying data formatting in
Lesson 5, we saw that
everything the user types into an application using the keyboard is
primarily a string and that you must convert it to the appropriate type
before using it. When you request a specific type of value from the user,
after the user has typed it and you decide to convert it to the appropriate
type, if your conversion fails, the program produces an error. The error is
of the FormatException class.
Here is a program that deals with a FormatException
exception:
using System;
class Program
{
static int Main()
{
double side;
Console.WriteLine("Square Processing");
try
{
Console.Write("Enter Side: ");
side = double.Parse(Console.ReadLine());
Console.WriteLine("\nSquare Characteristics");
Console.WriteLine("Side: {0}", side);
Console.WriteLine("Perimeter: {0}", side * 4);
}
catch(FormatException)
{
Console.WriteLine("\nYou typed an invalid number");
}
return 0;
}
}
Here is an example of running the program:
Square Processing
Enter Side: 25.9G
You typed an invalid number
Press any key to continue . . .
Application:
Using the FormatException Class
|
|
- Change the OrderProcessing.cs file as follows (this includes the
complete current version of the file):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace GeorgetownDryCleaningServices5
{
class OrderProcessing
{
#region Objects used to process an order
// Price of items
const decimal priceOneShirt = 0.95M;
const decimal priceAPairOfPants = 2.95M;
const decimal PriceOneDress = 4.55M;
const decimal TaxRate = 0.0575M; // 5.75%
CleaningOrderInfo cleaningOrder;
// Each of these sub totals will be used for cleaning items
private decimal SubTotalShirts;
private decimal SubTotalPants;
private decimal SubTotalDresses;
// Values used to process an order
private decimal TotalOrder;
private decimal TaxAmount;
private decimal SalesTotal;
private decimal AmountTended;
private decimal Difference;
#endregion
#region Actions used to process and present an order
public OrderProcessing()
{
cleaningOrder = new CleaningOrderInfo();
}
public void ProcessOrder()
{
Console.WriteLine("-/- Georgetown Cleaning Services -/-");
// Request order information from the user
Console.Write("Enter Customer Name: ");
cleaningOrder.CustomerName = Console.ReadLine();
Console.Write("Enter Customer Phone: ");
cleaningOrder.HomePhone = Console.ReadLine();
try
{
Console.Write("Enter the order date(mm/dd/yyyy): ");
cleaningOrder.OrderDate = DateTime.Parse(Console.ReadLine());
}
catch (FormatException)
{
Console.WriteLine("The value you entered is not a valid date");
}
try
{
Console.Write("Enter the order time(hh:mm AM/PM): ");
cleaningOrder.OrderTime = DateTime.Parse(Console.ReadLine());
}
catch
{
Console.WriteLine("The value you entered is not a valid time");
}
// Request the quantity of each category of items
try
{
Console.Write("Number of Shirts: ");
cleaningOrder.numberOfShirts = uint.Parse(Console.ReadLine());
if (cleaningOrder.numberOfShirts < uint.MinValue)
throw new OverflowException("Negative value not " +
"allowed for shirts");
}
catch (FormatException)
{
Console.WriteLine("The value you typed for the number of " +
"shirts is not a valid number");
}
try
{
Console.Write("Number of Pants: ");
cleaningOrder.numberOfPants = uint.Parse(Console.ReadLine());
}
catch(FormatException)
{
Console.WriteLine("The value you typed for the number of " +
"pair or pants is not a valid number");
}
try
{
Console.Write("Number of Dresses: ");
cleaningOrder.NumberOfDresses = uint.Parse(Console.ReadLine());
}
catch(FormatException)
{
Console.WriteLine("The value you typed for the number of " +
"dresses is not a valid number");
}
// Perform the necessary calculations
SubTotalShirts = cleaningOrder.numberOfShirts * priceOneShirt;
SubTotalPants = cleaningOrder.numberOfPants * priceAPairOfPants;
SubTotalDresses = cleaningOrder.NumberOfDresses * PriceOneDress;
// Calculate the "temporary" total of the order
TotalOrder = SubTotalShirts + SubTotalPants + SubTotalDresses;
// Calculate the tax amount using a constant rate
TaxAmount = TotalOrder * TaxRate;
// Add the tax amount to the total order
SalesTotal = TotalOrder + TaxAmount;
// Communicate the total to the user...
Console.WriteLine("\nThe Total order is: {0:C}", SalesTotal);
// and request money for the order
try
{
Console.Write("Amount Tended? ");
AmountTended = decimal.Parse(Console.ReadLine());
}
catch(FormatException)
{
Console.WriteLine("You were asked to enter an " +
"amount of money but...");
}
// Calculate the difference owed to the customer
// or that the customer still owes to the store
Difference = AmountTended - SalesTotal;
ShowReceipt();
}
private void ShowReceipt()
{
Console.WriteLine();
// Display the receipt
Console.WriteLine("====================================");
Console.WriteLine("-/- Georgetown Cleaning Services -/-");
Console.WriteLine("====================================");
Console.WriteLine("Customer: {0}", cleaningOrder.CustomerName);
Console.WriteLine("Home Phone: {0}", cleaningOrder.HomePhone);
Console.WriteLine("Order Date: {0:D}", cleaningOrder.OrderDate);
Console.WriteLine("Order Time: {0:t}", cleaningOrder.OrderTime);
Console.WriteLine("------------------------------------");
Console.WriteLine("Item Type Qty Unit/Price Sub-Total");
Console.WriteLine("------------------------------------");
Console.WriteLine("Shirts {0,3} {1,4} {2,6}",
cleaningOrder.numberOfShirts, priceOneShirt, SubTotalShirts);
Console.WriteLine("Pants {0,3} {1,4} {2,6}",
cleaningOrder.numberOfPants, priceAPairOfPants, SubTotalPants);
Console.WriteLine("Dresses {0,3} {1,4} {2,6}",
cleaningOrder.NumberOfDresses, PriceOneDress, SubTotalDresses);
Console.WriteLine("------------------------------------");
Console.WriteLine("Total Order: {0,6}", TotalOrder.ToString("C"));
Console.WriteLine("Tax Rate: {0,6}", TaxRate.ToString("P"));
Console.WriteLine("Tax Amount: {0,6}", TaxAmount.ToString("C"));
Console.WriteLine("Net Price: {0,6}", SalesTotal.ToString("C"));
Console.WriteLine("------------------------------------");
Console.WriteLine("Amount Tended: {0,6}", AmountTended.ToString("C"));
Console.WriteLine("Difference: {0,6}", Difference.ToString("C"));
Console.WriteLine("====================================");
}
#endregion
}
}
- Execute the application and test it. Here is an example:
-/- Georgetown Cleaning Services -/-
Enter Customer Name: Allen Dons
Enter Customer Phone: 202-442-0400
Enter the order date(mm/dd/yyyy): 7/14/2005
Enter the order time(hh:mm AM/PM): 8:46 AM
Number of Shirts: 5
Number of Pants: 2
Number of Dresses: 0
The Total order is: $11.26
Amount Tended? 15
- Press Enter:
====================================
-/- Georgetown Cleaning Services -/-
====================================
Customer: Allen Dons
Home Phone: 202-442-0400
Order Date: Thursday, July 14, 2005
Order Time: 8:46 AM
------------------------------------
Item Type Qty Unit/Price Sub-Total
------------------------------------
Shirts 5 0.95 4.75
Pants 2 2.95 5.90
Dresses 0 4.55 0.00
------------------------------------
Total Order: $10.65
Tax Rate: 5.75 %
Tax Amount: $0.61
Net Price: $11.26
------------------------------------
Amount Tended: $15.00
Difference: $3.74
====================================
- Close the DOS window
The OverflowException Exception
|
|
A computer application receives, processes, and produces
values on a regular basis as the program is running. To better manage these
values, as we saw when studying variables and data types in
Lesson 1 and
Lesson 2, the compiler uses
appropriate amounts of space to store its values. It is not unusual that
either you the programmer or a user of your application provides an value
that is beyond the allowed range based on the data type. For example, we saw
that a byte uses 8 bits to store a value and a combination of 8 bits can
store a number no more than 255. If you provide a value higher than 255 to
be stored in a byte, you get an error. Consider the following program:
using System;
// An Exercise class
class Exercise
{
static int Main()
{
byte NumberOfPages;
Console.Write("Enter the number of pages of the newspaper: ");
NumberOfPages = byte.Parse(Console.ReadLine());
Console.WriteLine("Number of Pages of the Newspaper: {0}\n", NumberOfPages);
}
return 0;
}
When a value beyond the allowable range is asked to be
stored in memory, the compiler produces (the expression is "throws" as we
will learn soon) an error of the OverflowException class. Here is an
example of running the program:
Enter the number of pages of the newspaper: 824
Unhandled Exception: System.OverflowException: Value was either too large or too
small for an unsigned byte.
at System.Byte.Parse(String s, NumberStyles style, IFormatProvider provider)
at System.Byte.Parse(String s)
at Exercise.Main() in c:\programs\msvcs .net 2003\project17\exercise.cs:line
11
As with the other errors, when this exception is thrown,
you should take an appropriate action.
The ArgumentOutOfRangeException Exception
|
|
Once again, when studying the techniques of converting
or formatting values in Lesson
5, we saw that a value was passed to the Parse() method of its
data type for analysis. For a primitive data type, the Parse() method
scans the string and if the string cannot be converted into a valid value,
the compiler usually produces a FormatException exception as we saw
above. Other classes such as DateTime also use a Parse()
method to scan the value submitted to it. For example, if you request a date
value from the user, the DateTime.Parse() method scans the string to
validate it. In US English, Parse() expects the user to type a string
in the form m/d/yy or mm/dd/yy or mm/dd/yyyy. Consider the following
program:
using System;
// An Exercise class
class Exercise
{
static int Main()
{
DateTime DateHired;
Console.Write("Enter Date Hired: ");
DateHired = DateTime.Parse(Console.ReadLine());
Console.WriteLine("Date Hired: {0:d}\n", DateHired);
return 0;
}
}
If the user types a value that cannot be converted into
a valid date, the compiler produces an ArgumentOutOfRangeException
exception. Here is an example of running the above program:
Enter Date Hired: 1244/04/258
Unhandled Exception: System.FormatException:
String was not recognized as a valid DateTime.
at System.DateTimeParse.Lex(Int32 dps, __DTString str, DateTimeToken dtok,
DateTimeRawInfo raw, DateTimeResult result, DateTimeFormatInfo& dtfi)
at System.DateTimeParse.Parse(String s,
DateTimeFormatInfo dtfi, DateTimeStyles styles)
at System.DateTime.Parse(String s, IFormatProvider provider, DateTimeStyles styles)
at System.DateTime.Parse(String s, IFormatProvider provider)
at System.DateTime.Parse(String s)
at Exercise.Main() in c:\programs\msvcs .net 2003\project17\exercise.cs:line 11
One way you can avoid this is to guide the user but
still take appropriate actions.
The DivideByZeroException Exception
|
|
Division by zero is an operation to always avoid. It is
so important that it is one of the most fundamental exceptions of the
computer. It is addressed at the core level even by the Intel and AMD
processors. It is also addressed by the operating systems at their level. It
is also addressed by most, if not all, compilers. It is also addressed by
most, if not all, libraries. This means that this exception is never
welcomed anywhere. The .NET Framework also provides it own class to face
this operation.
If an attempt to divide a value by 0 is performed, the
compiler produces a DivideByZeroException exception.
Application:
Ending the Lesson
|
|
- Close your programming environment
- When asked whether you want to save, click No
|
|