Книга: 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.

Оглавление книги


Генерация: 1.839. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз