Книга: C# 2008 Programmer
Throwing Exceptions Using the throw Statement
Throwing Exceptions Using the throw Statement
Instead of waiting for the system to encounter an error and raise an exception, you can programmatically raise an exception by throwing one. Consider the following example:
private int PerformDivision(int num1, int num2) {
if (num1 == 0) throw new ArithmeticException();
if (num2 == 0) throw new DivideByZeroException();
return num1 / num2;
}
In this program, the PerformDivision()
function throws an ArithmeticException
exception when num1
is zero and it throws a DivideByZeroException
exception when num2
is zero. Because there is no catch
block in PerformDivision()
, the exception is handled by the calling Main()
function. In Main()
, you can catch the ArithmeticException
exception like this:
class Program {
static void Main(string[] args) {
int num1, num2, result;
try {
Console.Write("Please enter the first number:");
num1 = int.Parse(Console.ReadLine());
Console.Write("Please enter the second number:");
num2 = int.Parse(Console.ReadLine());
Program myApp = new Program();
Console.WriteLine("The result of {0}/{1} is {2}", num1, num2,
myApp.PerformDivision(num1, num2));
} catch (ArithmeticException ex) {
Console.WriteLine("Numerator cannot be zero.");
} catch (DivideByZeroException ex) {
Console.WriteLine("Division by zero error.");
} catch (FormatException ex) {
Console.WriteLine("Input error");
} catch (Exception ex) {
Console.WriteLine(ex.Message);
}
Console.ReadLine();
}
private int PerformDivision(int num1, int num2) {
if (num1 == 0) throw new ArithmeticException();
if (num2 == 0) throw new DivideByZeroException();
return num1 / num2;
}
}
One interesting thing about the placement of the multiple catch blocks is that you place all specific exceptions that you want to catch first before placing generic ones. Because the Exception
class is the base of all exception classes, it should always be placed last in a catch block so that any exception that is not caught in the previous catch blocks is always caught. In this example, when the ArithmeticException
exception is placed before the DivideByZeroException
exception, IntelliSense displays an error (see Figure 12-3).
Figure 12-3
That's because the DivideByZeroException
is derived from the ArithmeticException
class, so if there is a division-by-zero exception, the exception is always handled by the ArithmeticException
exception and the DivideByZeroException
exception is never caught. To solve this problem, you must catch the DivideByZeroException
exception first before catching the ArithmeticException
exception:
static void Main(string[] args) {
int num1, num2, result;
try {
Console.Write("Please enter the first number:");
num1 = int.Parse(Console.ReadLine());
Console.Write("Please enter the second number:");
num2 = int.Parse(Console.ReadLine());
Program myApp = new Program();
Console.WriteLine("The result of {0}/{1} is {2}", num1, num2,
myApp.PerformDivision(num1, num2));
} catch (DivideByZeroException ex) {
Console.WriteLine("Division by zero error.");
} catch (ArithmeticException ex) {
Console.WriteLine("Numerator cannot be zero.");
} catch (FormatException ex) {
Console.WriteLine("Input error.");
} catch (Exception ex) {
Console.WriteLine(ex.Message);
}
Console.ReadLine();
}
The following shows the output when different values are entered for num1
and num2
:
Please enter the first number:5
Please enter the second number:0
Division by zero error.
Please enter the first number:0
Please enter the second number:5
Numerator cannot be zero.
Please enter the first number:a
Input error.
- Handling Multiple Exceptions
- 4.4.4 The Dispatcher
- About the author
- Chapter 7. The state machine
- Appendix E. Other resources and links
- Caveats using NAT
- Example NAT machine in theory
- Using Double Quotes to Resolve Variables in Strings with Embedded Spaces
- The final stage of our NAT machine
- Compiling the user-land applications
- The conntrack entries
- Untracked connections and the raw table