Upload
others
View
0
Download
0
Embed Size (px)
Citation preview
Visual C# - Penn P. Wu, PhD. 451
Lecture #15 Exception Handling
Introduction An exception, in terms of programming, is an unexpected or exceptional situation that could occur
when a program is executing. When an exception occurs, it typically causes interrupts to the
execution and for the runtime to pause for further instructions. An exception is not a syntactical
error; therefore, it may not be caught by the compiler.
In the following code, an attempt has been made to place non-numeric data in a numeric item.
Since the code does not have any syntax error, it will be compiled by the C# compiler into an
individual application (.exe). However, when being executed, it immediately raises a
System.FormatException because the string literal, “apple”, is not a correct format to be
converted to a numerical value.
using System;
using System.Windows.Forms;
public class Example
{
public static void Main()
{
int x;
x = Convert.ToInt32("apple");
}
}
The above example also leads to an arguable fact that many exceptions only occur when the
application encounter the situation that raises the exception issue. In the following example, the
instructor purposely skips the s[4] object to avoid the exceptional situation (in which “apple” must
be converted). Since “apple” is the exceptional situation and it has been avoided, the program will run smoothly without interrupts. This example also points to a fact that exceptional is often
foreseeable.
using System;
using System.Windows.Forms;
public class Example
{
public static void Main()
{
string[] s = { "12", "-18", "0", "137", "apple", "54"};
int x;
for (int i=0; i<s.Length; i++)
{
if (i==4) { continue; } //skip "apple"
else { x = Convert.ToInt32(s[i]); }
}
}
}
In arithmetic, no number can be divided by zero; therefore, attempting to divide a number by zero
is a known exception and defined by the .NET Framework as “System.DivideByZeroException”.
The following example, the for loop will hit the situation when the denominator (i) is zero.
Visual C# - Penn P. Wu, PhD. 452
Attempting to perform a calculation like 5
0 will “throw an exception” and immediately cause the
program to stop execution for an interrupt.
using System;
using System.Windows.Forms;
class MyException
{
static void Main(string[] args)
{
string str = "";
for (int i = -4; i <= 4; i++)
{
str += (5/i) + " ";
}
MessageBox.Show(str);
}
}
Remarkably, exception is not a syntax error. C# can compile the above code without any
compilation problem and will successfully compile the above code to produce an “.exe” program.
However, when executing this “.exe” program, C# will generate the following message.
Unhandled Exception: System.DivideByZeroException: Attempted to
divide by zero. at MyException.Main(String[] args)
As a matter of fact, C# compiler already resolved many foreseeable exceptions. For example,
when a quadratic equation, ax2 + bx + c = 0, is in a condition where b2-4ac < 0, there is no solution
in real numbers for this equation. The following is a sample code that demonstrates how this issue
is resolved. By the way, the solution of a quadratic equation, ax2 + bx + c = 0 is −𝑏±√𝑏2−4𝑎𝑐
2𝑎. The
output of is NaN, NaN because 14x2 + 4x + 7891 = 0 falls in the condition of b2-4ac < 0 and
“NaN” means “Not-a-Number”.
using System;
using System.Windows.Forms;
public class Example
{
public static void Main()
{
int a, b, c;
double x1, x2;
a = 14;
b = 4;
c = 7891;
x1 = (-b + Math.Sqrt(b*b-4*a*c)) / (2*a);
x2 = (-b - Math.Sqrt(b*b-4*a*c)) / (2*a);
MessageBox.Show(x1 + ", " + x2);
}
}
Since the exception is now expected, programmers should write codes to “handle” it. The term
“exception handling” means to write appropriate code to respond to an exception which could
Visual C# - Penn P. Wu, PhD. 453
occur when a computer program runs. The C# language comes with a set of well-developed
exception handling features to help programmers tackling with any unexpected or exceptional
situations that could occur when a program is running. The next few sections will guide students
through the use of the try, catch, and finally keywords to handle foreseeable exceptions.
The try..catch
structure
The simplest exception handling structure is the try..catch structure. The following illustrates the
structure. The “try” block is used by C# programmers to partition code that might be affected by
an exception while the associated “catch” block is used to handle any resulting exceptions.
try
{
// Code to try
}
catch (ExceptionType e)
{
// Code to handle the exception
}
The “catch” block requires programmers to specify the type of exception to properly catch. The
exception type should be derived from Exception. By the way, the specified exception type is also
known as the “exception filter”.
The .NET Framework defines the System.Exception class. An instance of the Exception class can
represent an exception that occur during application execution. When an exception occurs, either the system or the currently executing application reports it by throwing an exception request that
contains information about the exception. One important information is the type of exception that
provides a clue for exception handling. Interestingly, the System.Exception class is the base class
for all exceptions. The following is a list of commonly seen exception defined by the .NET
Framework. They are derived from the System.Exception class.
Exception class Description ArithmeticException A base class for exceptions that occur during arithmetic
operations, such as System.DivideByZeroException and
System.OverflowException.
ArrayTypeMismatchException Thrown when a store into an array fails because the
actual type of the stored element is incompatible with
the actual type of the array.
DivideByZeroException Thrown when an attempt to divide an integral value by
zero occurs.
FormatException Thrown when the format of an argument is invalid, or
when a composite format string is not well formed.
IndexOutOfRangeException Thrown when an attempt to index an array via an index
that is less than zero or outside the bounds of the array.
InvalidCastException Thrown when an explicit conversion from a base type or
interface to a derived type fails at run time.
NullReferenceException Thrown when a null reference is used in a way that
causes the referenced object to be required.
OutOfMemoryException Thrown when an attempt to allocate memory (via new)
fails.
Visual C# - Penn P. Wu, PhD. 454
OverflowException Thrown when an arithmetic operation in a checked
context overflow.
StackOverflowException Thrown when the execution stack is exhausted by
having too many pending method calls; typically,
indicative of very deep or unbounded recursion.
TypeInitializationException Thrown when a static constructor throws an exception,
and no catch clauses exists to catch it.
An arithmetic operation can produce a result that is outside the range of the data type returned by
the operation. For example, the System.Int16 type only support values in the range from -32,768
to 32,767. Any number outside the supported range will cause an exception known as
“OverflowException” which is thrown when an arithmetic, casting, or conversion operation
results in an overflow. In the following example, the variable “x” is declared as System.Int16 type
and is assigned a value 32766 which is almost the largest value the System.Int16 type can handle.
The expression, x*x, produces a number that is much larger than 32766 and cannot be handled by
the Int16 type.
using System;
using System.Windows.Forms;
public class Example
{
static void Main()
{
System.Int16 x = 32766;
MessageBox.Show(Convert.ToInt16(x*x) + "");
}
}
Interestingly, the above code will compile to produce an “.exe” file. However, the execution of the
“.exe” file will be interrupted for an unhandled exception and the execution engine will display the
following message.
Unhandled Exception: System.OverflowException: Value was either
too large or too small for an Int16.
The following demonstrates how to use a try..catch structure to catch and then handle the
exception. The “try” block will attempt to run the statement that could throw an exception. When
the exception is thrown, the “catch” block will immediately take action to use the
“Convert.ToInt64()” method to handle the “exceptional” calculation. Since the
“Convert.ToInt64()” method can support up to 9,223,372,036,854,775,807, the calculation will go
through without any run-time interrupt(s). In the “catch” block, there is an instance “e” of the
OverflowException class which will represent the exception after the exception occurs. The read-
only “Message” property of the OverflowException class holds the message (such as “Value
was either too large or too small for an Int16.”).
using System;
using System.Windows.Forms;
public class Example
{
static void Main()
{
System.Int16 x = 32766;
try
Visual C# - Penn P. Wu, PhD. 455
{
MessageBox.Show(Convert.ToInt16(x*x) + "");
}
catch (OverflowException e)
{
MessageBox.Show(e.Message + "\n" + Convert.ToInt64(x*x));
}
}
}
It is necessary to note that OverflowException is a specialized subset of the System.Exception
class. Therefore, programmers can use an instance of the System.Exception class to handle any exception type derived from the System.Exception class (such as the OverflowException type of
exception), as shown below. Interestingly, Microsoft suggests programmers to always specify an
object argument derived from System.Exception in the catch block for a better and faster
exception handling. In a nutshell, although InvalidCastException is an exception that is thrown
for invalid casting or explicit conversion, it cannot handle the NullReferenceException
exception.
using System;
using System.Windows.Forms;
public class Example
{
static void Main()
{
System.Int16 x = 32766;
try
{
MessageBox.Show(Convert.ToInt16(x*x) + "");
}
catch (Exception e)
{
MessageBox.Show(e.Message + "\n" + Convert.ToInt64(x*x));
}
}
}
The FormatException is thrown when the format of an argument is invalid, or when a composite format string is not well formed. In the following example, “forty-five” is a string that cannot be
converted to int type due to its format incompatibility. Yet, a string “45” is acceptable.
using System;
using System.Windows.Forms;
class Example
{
static void Main()
{
string x = "forty-five";
try
{
int y = Convert.ToInt32(x);
}
catch (FormatException e)
{
MessageBox.Show(e.ToString() + "");
}
Visual C# - Penn P. Wu, PhD. 456
}
}
The OutOfMemoryException is triggered by allocation instructions and is thrown by the
execution engine; it can occur during any allocation call during runtime. However, this is a
foreseeable exception and should be handled by the programmer. The following is a simple
program that raises out-of-memory exception in C# because it attempts to allocate a very large
size of memory space for the variable “a” and the requested size is far larger than what the
physical memory can allocate. By the way, the instructor purposely chooses not to handle this
foreseeable exception.
using System;
class Example
{
static void Main()
{
string value = new string('a', int.MaxValue);
}
}
This code raise the following exception because it attempts to allocate a string that is extremely
large and would occupy four gigabytes of memory. However, the OutOfMemoryException is
thrown by the runtime because this is not possible. The intention of the program is to demonstrate
the exception itself and not to provide a realistic example.
Unhandled Exception: OutOfMemoryException
The following demonstrates how to handle this exception using a try..catch structure. In the
“catch” block, the instructor purposely declare a string variable named “str” which obtain the
exception message from the “Message” property of the OutOfMemoryException class and then
nullifies it.
using System;
class Example
{
static void Main()
{
try
{
string value = new string('a', int.MaxValue);
}
catch (OutOfMemoryException e)
{
string str = e.Message;
string value = new string('a', 1024);
str = null;
}
}
}
The following code will cause a NullReferenceException exception because object reference
cannot be casted to a type. NullReferenceException is the exception that is thrown when there is
an attempt to dereference a null object reference.
Visual C# - Penn P. Wu, PhD. 457
object o2 = null;
int i2 = (int) o2; // attempt to cast o2 to integer
Programmers can implement a try..catch structure to attempt to cast a null object and handle the
raised “NullReferenceException” exception.
object o2 = null;
try
{
int i2 = (int) o2; // attempt to cast o2 to integer
}
The following is the sample “catch” block that can handle the NullReferenceException
exception. The Message property gets a message that describes the current exception. The trick is
to pass the exception message from runtime to string variable “str”, thus, the exception message
will not be displayed on the screen and the program will run without interruption. By the way, the
“str” variable will be nullified.
catch (NullReferenceException e)
{
string str = e.Message;
str = null;
}
The following is another example in which the “ToString()” method will convert the default
message generated by the “e” instance to a string literal.
catch (NullReferenceException e)
{
string str = e.ToString();
str = null;
}
The following demonstrates how to use a try..catch structure to handle the exception that attempts
to divide a number by zero. When i=0, the continue statement will force the for loop to skip the
current iteration. The “Message” property will pass the default exception message to the “str”
variable.
using System;
using System.Windows.Forms;
class Example
{
static void Main(string[] args)
{
string str = "";
for (int i = -4; i <= 4; i++)
{
try
{
str += (5/i) + "\n";
}
catch (DivideByZeroException e)
{
str += e.Message + "\n";
Visual C# - Penn P. Wu, PhD. 458
continue; // optional statement
}
}
MessageBox.Show(str);
}
}
The above code will first attempt to let 5 divides by the current value of i. The division should go
through unless i = 0. When i = 0, the exception happens, and this exception will be caught by the
catch statement. In the catch statement there is a parameter e declared as Exception type which
represents errors that occur during application execution. According to the above code, the
exception message is assigned to a variable named “str”, so it will not bounce to the console
screen. The continue statement also forces the run-time to jump to next loop (i=1). With this
exception handling mechanism. The above program will run smoothly without any interruption.
As illustrates in the above codes, a “catch” block can specify the type of exception to catch. The
type specification is called an exception filter. The following demonstrates how to use a try..catch
structure to handle the IndexOutOfRangeException exception which is thrown only when an
attempt is made to access an element of an array with an index that is outside the bounds of the
array. In the following, the x array can only have 5 elements, but the for loop attempts to create 8
elements.
int[] x = new int[5];
for (int i=0; i<=7; i++)
{
x[i] = i * i;
}
The above code will cause the following message because the index is in a range from 0 to 4 and
x[5], x[6], and x[7] do not exist.
Unhandled Exception: System.IndexOutOfRangeException: Index was
outside the bounds of the array.....
The following demonstrates how to add a try..catch structure to handle the IndexOutOfRangeException exception.
using System;
class Example
{
static void Main(string[] args)
{
int[] x = new int[5];
for (int i=0; i<=7; i++)
{
try
{
x[i] = i * i;
}
catch(System.IndexOutOfRangeException e)
{
string str = e.Message;
str = null;
continue;
Visual C# - Penn P. Wu, PhD. 459
}
}
}
}
It is possible to two or more “catch” blocks in the same try..catch structure with the premise that
the order of every “catch” block must be well arranged because all “catch” blocks are tested in a
linear order. A general principle is to catch the more specific exceptions before the less specific
ones. The compiler will display an exception message if the second specified exception is caught
before the first specified exception; therefore, a missed “catch” block will never be reached. In the
following example, two “catch” block are placed in sequence. The most specific exception, which
comes first, is caught.
using System;
using System.Windows.Forms;
class MyException
{
static void ProcessString(string s)
{
if (s == null)
{
throw new ArgumentNullException();
}
}
static void Main()
{
try
{
string s = null;
ProcessString(s);
}
// Most specific:
catch (ArgumentNullException e)
{
MessageBox.Show(e.ToString());
}
// Least specific:
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
}
}
The throw
statement
The throw statement can be used in a “catch” block to re-throw the exception that is caught by the
catch statement. In the following example, the “catch” block already handles the
“NullReferenceException” exception; therefore, the exceptional message will not be displayed.
Interestingly, the additional “throw” statement redundantly re-throws the exception again, so the
exceptional message is redundantly displayed.
using System;
using System.Windows.Forms;
public class Example
{
public static void Main()
{
Visual C# - Penn P. Wu, PhD. 460
object o2 = null;
try
{
int i2 = (int) o2; // Error
}
catch (NullReferenceException e)
{
string str = e.Message; //exception handle
str = "";
throw;
}
}
}
Although the above example simply re-throws the handled exceptional message, the “throw”
statement is typically used to catch an exception and throw a different exception. The following
example demonstrates how to specify the exception to catch and display a custom exception
message. By the way, the exception specified in a “throw” statement is known as the inner exception.
catch (NullReferenceException e)
{
string str = e.Message;
str = "";
throw new InvalidCastException("My customized error message.");
}
The following example, use the conditional operator (?:) to test the length of a string literal
(“apple”). If it has fewer than 6 characters in length, the “throw” statement will throw a generic exception.
using System;
using System.Windows.Forms;
class Example
{
public static void Main()
{
string s = "apple";
char c = s.Length >= 6 ? s[5] : throw new Exception("Bad");
MessageBox.Show(c + "");
}
}
In the following example, the “try” block contains a call to the ProcessString method that may
cause an exception. The catch clause contains the exception handler that just displays a message
on the screen. When the throw statement is called from within the class, the system looks for the
“catch” statement and displays the message Exception caught.
using System;
using System.Windows.Forms;
class MyException
{
Visual C# - Penn P. Wu, PhD. 461
static void ProcessString(string s)
{
if (s == null)
{
throw new ArgumentNullException();
}
}
static void Main()
{
string s = null; // For demonstration purposes.
try
{
ProcessString(s);
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
}
}
The output in the console is:
System.ArgumentNullException: Value cannot be null. at
TryFinallyTest.Main() Exception caught.
a try..catch..
finally
statement
A finally block contains code that will be executed regardless of whether or not an exception is
thrown in the “try” block, such as releasing resources that are allocated in the try block. A
“finally” block also enables programmers to clean up actions that are performed in a “try” block. If present, the finally block will be the last to execute, typically after the “try” block and any
matched “catch” block. In a nutshell, a “try” block requires one or more associated catch blocks,
or a finally block, or both. All codes in the “finally” block will always run regardless of whether
an exception is thrown or a “catch” block matching the exception type is found. The following is a
generic syntax of the “finally” block in C#.
try
{
// Code to try goes here.
}
catch (SomeSpecificException ex)
{
// Code to handle the exception goes here.
}
finally
{
// Code to execute after the try block goes here.
}
The following demonstrates how to use a try..catch..finally structure to handle an
IndexOutOfRangeException. The “x” array is limited to host only 27 elements. The first element
has an index of 0 and the last element has an index of 26. However, the while loop attempts to stuff it with 35 elements. When the counter variable i is larger than 26, an
IndexOutOfRangeException is raised. The “catch” block will catch the exceptions. The increment
of the while loop is done within the “finally” block so that the while loop will complete its
iterations (from 0 to 34) even when exceptions occur.
using System;
using System.Windows.Forms;
Visual C# - Penn P. Wu, PhD. 462
public class Example
{
public static void Main()
{
string str = "";
int[] x = new int[27];
int i = 0;
while (i<35)
{
try
{
x[i] = i;
str += x[i] + " ";
}
catch(IndexOutOfRangeException e)
{
string msg = e.Message;
msg = null;
continue;
}
finally
{
i++;
}
}
MessageBox.Show(str);
}
}
In the following example, an invalid conversion statement causes an InvalidCastException
exception. The exception is handled and the finally block will display the value of i regardless of
the existence of exception.
using System;
using System.Windows.Forms;
class Example
{
static void Main(string[] args)
{
int i = 123;
string s = "apple";
object obj = s;
try
{
i = (int) obj;
}
catch (InvalidCastException e)
{
string str = e.Message;
str = null;
}
finally
{
MessageBox.Show(i.ToString());
Visual C# - Penn P. Wu, PhD. 463
}
}
}
In the following example, the “try” block will attempt to assign the square of current i (because the
expression i*i) as an element of the “x” array; the “catch” block will catch the
IndexOutOfRangeException exception and display a dash (“-“) as output; and the “finally” block
will display the current value of i regardless the occurrence of exception.
using System;
using System.Windows.Forms;
class Example
{
public static void Main(string[] args)
{
string str = "x[i]\ti\n";
int[] x = new int[5];
for (int i=0; i<=7; i++)
{
try
{
x[i] = i * i;
str += x[i] + "\t";
}
catch(System.IndexOutOfRangeException e)
{
string msg = e.Message;
msg = null;
str += "-\t";
}
finally
{
str += i + "\t\n";
}
}
MessageBox.Show(str);
}
}
If no foreseeable exception is expected, programmers can clean up any resources that are allocated
in a try block. In the following example, the “finally” block is used to close a file that is opened in
the “try” block. Notice that the state of the file handle is checked before the file is closed. If the try
block cannot open the file, the file handle still has the value null and the finally block does not try
to close it. Alternatively, if the file is opened successfully in the try block, the finally block closes
the open file.
using System;
using System.Windows.Forms;
using System.IO;
class Example
{
static void Main()
{
Visual C# - Penn P. Wu, PhD. 464
FileStream file = null;
FileInfo fileinfo = new FileInfo("C:\\file.txt");
try
{
file = fileinfo.OpenWrite();
file.WriteByte(0xF);
}
finally
{
file.Close();
}
}
}
Practical
Examples
Many applications requires user inputs with specific format. For example, the unit price of a
product must be numerical values that consist of digits only. A value like "apple" should not be
acceptable. Since user inputs are treated as string literals, a value like “34.57” must be converted
from a string to a double type using tools like the “Convert.ToDouble()” method. The following,
for example, will raise a FormatException.
double unitPrice = Convert.ToDouble("apple");
The following, however, will convert the data type from string to double.
double unitPrice = Convert.ToDouble("34.57");
In a nutshell, the following could possibly raise an unhandled exception when “orange”, “a12”,
“34.5s”, or even “$25.78” is entered as user input due to format incompatibility.
A try..catch structure could resolve this issue. With an assumption that “textBox1” takes the user
input of “unit price”. The following demonstrates how to use a try..catch structure to attempt to
convert a string entered to “textBox1” to double. If the conversion cannot succeed, a
FormatException is thrown to indicate that the user input is not given with a value format. The
“catch” block will handle the exception and the application will not be forced to terminate with an
interrupt.
string n1 = textBox1.Text;
.........
try
{
Convert.ToDouble(n1);
}
catch(FormatException ex)
{
string str = ex.Message;
str = null;
textBox3.Text += "Value of unit price must be number." +
Environment.NewLine;
}
Question 1. Given the following code segment, what possible exception will it throw?
for (int i = -4; i <= 4; i++) {
str += (5/i) + " ";
}
A. ArithmeticException
B. OverflowException
Visual C# - Penn P. Wu, PhD. 465
C. IndexOutOfRangeException
D. DivideByZeroException
2. Given the following code segment, what possible exception will it throw?
int value = 987654321;
int cube = value * value * value;
MessageBox.Show(Convert.ToInt16(cube)+"");
A. ArithmeticException
B. OverflowException
C. IndexOutOfRangeException
D. DivideByZeroException
3. Given the following code segment, what possible exception will it throw?
string value = new string('a', int.MaxValue);
A. OutOfMemoryException
B. OverflowException
C. StackOverflowException
D. TypeInitializationException
4. Given the following code, which can display the error in a message box when exception
happens?
catch (NullReferenceException e) { .... }
A. e.MessageBox.Show();
B. MessageBox.Show(e);
C. MessageBox.Show(Message(e)); D. MessageBox.Show(e.ToString());
5. Given the following code segment, what possible exception will it throw?
int[] x = new int[5];
for (int i=0; i<=7; i++) {
x[i] = i * i;
}
A. ArithmeticException B. OverflowException
C. IndexOutOfRangeException
D. DivideByZeroException
6. How many times will the following catch statement display the error message on screen?
catch (NullReferenceException e) { throw; }
A. 1
B. 2
C. 3
D. 4
7. Which statement is correct?
A. A finally block enables you to clean up actions that are performed in a try block.
B. If present, the finally block executes last, after the try block and any matched catch block.
Visual C# - Penn P. Wu, PhD. 466
C. A finally block always runs, regardless of whether an exception is thrown or a catch block
matching the exception type is found.
D. All of the above.
8. Given the following code, which statement is incorrect?
string str = "";
int[] x = new int[5];
for (int i=0; i<=7; i++) {
try {
x[i] = i;
str += x[i] + " ";
}
catch(System.IndexOutOfRangeException) {
if (i>= x.Length) { // the Length property
continue;
}
}
}
MessageBox.Show(str);
A. The x array has 5 elements. B. The for loop will executes 8 times.
C. The result is 0 1 2 3 4.
D. All of the above.
9. When an ArgumentNullException exception is thrown, which exception will be caught?
catch(IndexOutOfRangeException e) {
MessageBox.Show("1" + e.ToString());
}
catch (ArgumentNullException e) {
MessageBox.Show("2" + e.ToString());
}
catch (Exception e) {
MessageBox.Show("3" + e.ToString());
}
A. MessageBox.Show("1" + e.ToString());
B. MessageBox.Show("2" + e.ToString());
C. MessageBox.Show("3" + e.ToString());
D. All of the above
10. The __ exception is the exception that is thrown when an arithmetic, casting, or conversion
operation in a checked context results in an overflow.
A. ArithmeticException
B. OverflowException
C. OutOfMemoryException D. StackOverflowException
Visual C# - Penn P. Wu, PhD. 467
Lab #15 Exception Handling
Learning Activity #1:
1. Create the C:\cis218 directory if it does not exist.
2. Launch the Development Command Prompt.
3. Under the C:\cis218 directory, use Notepad to create a new text file named lab15_1.cs with the following
contents:
//incorrect
using System;
using System.Windows.Forms;
public class Example
{
static void Main()
{
int value = 987654321;
double cube = Math.Pow(value, 3);
MessageBox.Show(Convert.ToInt16(cube)+""); // exception
}
}
4. Compile and test the program to observe the error message.
.....error CS0266: Cannot implicitly convert type 'double' to 'int'. An explicit
conversion exists (are you missing a cast?)
5. Edit the source file and change the source code to the following:
// solution
using System;
using System.Windows.Forms;
public class Example
{
static void Main()
{
string str = "";
int value = 987654321;
double cube = Math.Pow(value, 3);
try
{
str = Convert.ToInt16(cube) + "";
}
catch (OverflowException e)
{
string msg = e.ToString();
msg = null; // nullify
str = Math.Pow((long) value, 3) + "";
Visual C# - Penn P. Wu, PhD. 468
}
MessageBox.Show(str); // exception
}
}
6. Compile and test the program. A sample output looks:
7. Download the “assignment template”, and rename it to lab15.doc if necessary. Capture a screen shot similar to
the above and paste it to the Word document named lab15.doc (or .docx).
Learning Activity #2:
1. Under the C:\cis218 directory, use Notepad to create a new text file named lab15_2.cs with the following
contents:
using System;
using System.Windows.Forms;
public class Example
{
public static void Main(string[] args)
{
string str = "";
for (int i = -4; i <= 4; i++)
{
str += (5/i) + " "; // exception – attempt to divide by 0
}
MessageBox.Show(str);
}
}
2. Compile and test the program to observe the error message.
Unhandled Exception: System.DivideByZeroException: Attempted to divide by zero.
at Example.Main(String[] args)
3. Re-open the source file and change the source code to the following:
using System;
using System.Windows.Forms;
public class Example
{
public static void Main(string[] args)
{
string str = "";
for (int i = -4; i <= 4; i++)
{
try
Visual C# - Penn P. Wu, PhD. 469
{
str += (5/i) + " ";
}
catch (DivideByZeroException e)
{
string msg = e.Message;
msg = null; //nullify msg
str += "NaN ";
}
}
MessageBox.Show(str);
}
}
4. Compile and test the program. A sample output looks:
5. Capture a screen shot similar to the above and paste it to the Word document named lab15.doc (or .docx).
Learning Activity #3:
1. Under the C:\cis218 directory, use Notepad to create a new text file named lab15_3.cs with the following
contents:
using System;
using System.Windows.Forms;
class Example
{
static void Main(string[] args)
{
string str = "Elements of x are:\n";
int[] x = new int[5];
for (int i=0; i<=7; i++)
{
x[i] = i * i;
}
for (int i=0; i<x.Length; i++)
{
str += x[i] + " ";
}
MessageBox.Show(str);
}
}
2. Compile and test the program to observe the error message.
Unhandled Exception: System.IndexOutOfRangeException: Index was outside the bounds
of the array.
at Example.Main(String[] args)
Visual C# - Penn P. Wu, PhD. 470
3. Re-open the source file and change the source code to the following:
using System;
using System.Windows.Forms;
class Example
{
static void Main(string[] args)
{
string str = "Elements of x are:\n";
int[] x = new int[5];
for (int i=0; i<=7; i++)
{
try
{
x[i] = i * i;
}
catch(System.IndexOutOfRangeException e)
{
string msg = e.Message;
msg = null;
continue;
}
finally
{
if (i<x.Length) // the Length property
{
str += x[i] + " ";
}
}
}
str += "\nThe number of element is " + x.Length + "\n";
for (int i=0; i<x.Length; i++)
{
str += x[i] + " ";
}
MessageBox.Show(str);
}
}
4. Compile and test the program. A sample output looks:
5. Capture a screen shot similar to the above and paste it to the Word document named lab15.doc (or .docx).
Learning Activity #4: OutOfMemoryException
1. Under the C:\cis218 directory, use Notepad to create a new text file named lab15_4.cs with the following
contents:
using System;
Visual C# - Penn P. Wu, PhD. 471
using System.Windows.Forms;
class Example
{
static void Main()
{
int[] LargeArray = new int[987654321];
for (int i=0; i<LargeArray.Length; i++)
{
LargeArray[i] = i;
}
string str = "The last element is " + LargeArray[LargeArray.Length - 1] +
Environment.NewLine;
str += "The index is: " + (LargeArray.Length - 1);
MessageBox.Show(str);
}
}
2. Compile and test the program to observe the error message.
Unhandled Exception: OutOfMemoryException.
3. Re-open the source file and change the source code to the following:
using System;
using System.Windows.Forms;
class Example
{
static void Main()
{
int[] LargeArray;
try
{
LargeArray = new int[987654321];
}
catch(OutOfMemoryException e)
{
string msg = e.ToString();
msg = null;
// set the Length to the largest possible value of an Int16.
LargeArray = new int[Int16.MaxValue];
}
for (int i=0; i<LargeArray.Length; i++)
{
LargeArray[i] = i;
}
string str = "The last element is " + LargeArray[LargeArray.Length - 1] +
Environment.NewLine;
str += "The index is: " + (LargeArray.Length - 1);
MessageBox.Show(str);
}
}
Visual C# - Penn P. Wu, PhD. 472
4. Compile and test the program. A sample output looks:
5. Capture a screen shot similar to the above and paste it to the Word document named lab15.doc (or .docx).
Learning Activity #5:
1. Under the C:\cis218 directory, use Notepad to create a new text file named lab15_5.cs with the following contents:
using System;
using System.Windows.Forms;
using System.Drawing;
public class Form1 : Form
{
private TextBox textBox1, textBox2, textBox3;
public Form1()
{
Label label1 = new Label();
label1.Text = "Enter the unit price:";
label1.Size = new Size(120, 30);
label1.Location = new Point(10, 10);
this.Controls.Add(label1);
textBox1 = new TextBox();
textBox1.Size = new Size(50, 30);
textBox1.Location = new Point(130, 10);
this.Controls.Add(textBox1);
Label label2 = new Label();
label2.Text = "Enter the Quantity:";
label2.Size = new Size(120, 30);
label2.Location = new Point(10, 40);
this.Controls.Add(label2);
textBox2 = new TextBox();
textBox2.Size = new Size(50, 30);
textBox2.Location = new Point(130, 40);
this.Controls.Add(textBox2);
Button button1 = new Button();
button1.Text = "Check";
button1.Location = new Point(190, 40);
button1.AutoSize = true;
button1.Click += new EventHandler(button1_Click);
this.Controls.Add(button1);
textBox3 = new TextBox();
textBox3.Size = new Size(265, 100);
textBox3.Location = new Point(10, 80);
textBox3.Multiline = true;
this.Controls.Add(textBox3);
}
private void button1_Click(object sender, EventArgs e) //event handler
Visual C# - Penn P. Wu, PhD. 473
{
string n1 = textBox1.Text;
string n2 = textBox2.Text;
try // check textbox1
{
Convert.ToDouble(n1);
}
catch(FormatException ex)
{
string str = ex.Message;
str = null;
textBox3.Text += "Value of unit price must be number." +
Environment.NewLine;
}
try //check textbox2
{
Convert.ToDouble(n2);
}
catch(FormatException ex)
{
string str = ex.Message;
str = null;
textBox3.Text += "Value of Quantity must be number." +
Environment.NewLine;
}
try
{
textBox3.Text = "Total: $" +
Math.Round((Convert.ToDouble(n1) * Convert.ToDouble(n2)), 2) +
Environment.NewLine;
}
catch(FormatException ex)
{
string str = ex.Message;
str = null;
}
}
[STAThread]
public static void Main()
{
Application.Run(new Form1());
}
}
2. Compile and test the program. The output looks:
Visual C# - Penn P. Wu, PhD. 474
and
3. Capture a screen shot similar to the above and paste it to the Word document named lab15.doc (or .docx).
Submittal
1. Complete all the 5 learning activities.
2. Create a .zip file named lab15.zip containing ONLY the following self-executable files.
• Lab15_1.exe
• Lab15_2.exe
• Lab15_3.exe
• Lab15_4.exe
• Lab15_5.exe
• Lab15.doc (or lab15.docx) [You may be given zero point if this Word document is missing]
3. Log in to course site and enter the course site.
4. Upload the zipped file as response to question 11.
Programming Exercise:
1. Use Notepad to create a new file named ex15.cs with the following heading lines (be sure to replace
YourFullNameHere with the correct one):
//File Name: ex15.cs
//Programmer: YourFullNameHere
using System;
using System.Windows.Forms;
public class Example
{
public static void Main()
{
string str = "";
int[] x = new int[20];
int i = 0;
while (i<25)
{
x[i] = i;
str += x[i] + " ";
i++;
}
MessageBox.Show(str);
}
}
Visual C# - Penn P. Wu, PhD. 475
2. Add a try..catch statement with an IndexOutOfRangeException exception to above code so the following
message can be displayed without any error or interrupts. DO NOT USE if..else to handle the exception.
6. Download the “programming exercise template”, and rename it to ex15.doc. Capture a screen shot similar to the
above figure and then paste it to the Word document named “ex15.doc” (or .docx).
7. Compress the source code (ex15.cs), the executable (ex15.exe), and the Word document (ex15.doc or .docx) to
a .zip file named “ex15.zip”. You may be given zero point if any of the required file is missing.
Grading Criteria:
• You must be the sole author of the codes.
• You must meet all the requirements in order to earn credits.
• No partial credit is given.