Techniques of Using Exceptions

Introduction

The Exception class is equipped with a Message property that holds a string about the error that occurred. The message of this property may not be particularly useful to a user. Fortunately, you can create your own message and pass it to the Exception class. To be able to receive custom messages, the Exception class provides the following constructor:

public Exception(string message);

Besides using this class or one of its derived classes in a catch clause, you can call this constructor to give a new and customized implementation of the exception.

ApplicationPractical Learning: Using Exceptions

  1. Start Microsoft Visual Studio
  2. To create a new application, on the main menu, click File -> New -> Project...
  3. In the middle list, click Empty Project (.NET Framework)
  4. Change the Name to RealEstate1
  5. Click OK
  6. On the main menu, click View -> Class View
  7. To create a new class, in the Class View, right-click RealEstate1 -> Add -> Class...
  8. Type Residence as the name of the class
  9. Click Add
  10. Change the document as follows:
    namespace RealEstate1
    {
        public enum PropertyCondition
        {
            Unknown,
            Excellent,
            Good,
            NeedsMaintenance,
            BadShape
        }
    
        public class Residence
        {
            public int               PropertyNumber { get; set; }
            public PropertyCondition Condition      { get; set; } = PropertyCondition.Unknown;
            public int               Bedrooms       { get; set; }
            public double            Bathrooms      { get; set; }
            public int               YearBuilt      { get; set; }
            public double            MarketValue    { get; set; }
        }
    }
  11. On the main menu, click Project -> Add Class...
  12. Type House as the name of the class
  13. Press Enter
  14. To derive a class, change the document as follows:
    namespace RealEstate1
    {
        public class House : Residence
        {
            public int  Stories          { get; set; }
            public bool FinishedBasement { get; set; }
            public bool IndoorGarage     { get; set; }
        }
    }
  15. In the Class View, right-click RealEstate1 -> Add -> Class...
  16. Type Condominium
  17. Press Enter
  18. To create another class based on the Residence class, change the document as follows:
    namespace RealEstate1
    {
        public class Condominium : Residence
        {
            public bool HandicapAccessible { get; set; }
        }
    }
  19. To create a new class, in the Solution Explorer, right-click RealEstate1 -> Add -> Class...
  20. Type PropertyListing
  21. Click Add
  22. Change the file as follows:
    using System;
    
    namespace RealEstate1
    {
        public enum PropertyType
        {
            Unknown,
            SingleFamily,
            Townhouse,
            Condominium
        }
    
        public class PropertyListing
        {
            public Residence    Residence    { get; set; }
            public House    House        { get; set; }
            public Condominium  Condominium  { get; set; }
            public PropertyType Type         { get; set; }
    
            public PropertyListing()
            {
                Residence   = new Residence();
                House       = new House();
                Condominium = new Condominium();
            }
    
            public void CreateListing()
            {
                string answer    = "n";
                int    propType  = 1;
                int    condition = 1;
    
                Console.Title = "Altair Realtors - Property Creation";
                Console.WriteLine(" =//= Altair Realtors =//=");
                Console.WriteLine("--------------------------------------------------------------");
                Console.WriteLine("-=- Property Creation -=-");
                try
                {
                   Console.WriteLine("Types of Properties");
                   Console.WriteLine("1. Single Family");
                   Console.WriteLine("2. Townhouse");
                   Console.WriteLine("3. Condominium");
                   Console.WriteLine("4. Don't Know");
                   Console.Write("Enter Type of property:                           ");
                   propType = short.Parse(Console.ReadLine());
                }
                catch (FormatException ex)
                {
                   Console.WriteLine(ex.Message);
                }
    
                Random rndNumber = new Random();
                Residence.PropertyNumber = rndNumber.Next(100001, 999999);
    
                Console.WriteLine("--------------------------------------------------------------");
                try
                {
                   Console.WriteLine("Properties Conditions");
                   Console.WriteLine("1. Excellent");
                   Console.WriteLine("2. Good (may need minor repair)");
                   Console.WriteLine("3. Needs Maintenance");
                   Console.Write("4. In Bad Shape (property needs ");
                   Console.WriteLine("major maintenance or rebuild)");
                   Console.Write("Enter Property Condition:                         ");
                   condition = short.Parse(Console.ReadLine());
                }
                catch (FormatException ex)
                {
                   Console.WriteLine(ex.Message);
                }
    
                if (condition == 1)
                    Residence.Condition = PropertyCondition.Excellent;
                else if (condition == 2)
                    Residence.Condition = PropertyCondition.Good;
                else if (condition == 3)
                    Residence.Condition = PropertyCondition.NeedsMaintenance;
                else if (condition == 4)
                    Residence.Condition = PropertyCondition.BadShape;
                else
                    Residence.Condition = PropertyCondition.Unknown;
    
                Console.WriteLine("--------------------------------------------------------------");
                switch ((PropertyType)propType)
                {
                    case PropertyType.SingleFamily:
                        Type = PropertyType.SingleFamily;
                        try
                        {
                            Console.Write("How many stories (levels)?                        ");
                            House.Stories = short.Parse(Console.ReadLine());
                        }
                        catch (FormatException ex)
                        {
                           Console.WriteLine(ex.Message);
                        }
                        try
                        {
                            Console.Write("Does it have an indoor car garage (y/n):          ");
                            answer = Console.ReadLine();
                            if ((answer == "y") || (answer == "Y"))
                                House.IndoorGarage = true;
                            else
                                House.IndoorGarage = false;
                        }
                        catch (FormatException)
                        {
                           Console.WriteLine("Invalid Indoor Car Garage Answer");
                        }
                        try
                        {
                            Console.Write("Is the basement finished(y/n):                    ");
                            answer = Console.ReadLine();
                            if ((answer == "y") || (answer == "Y"))
                                House.FinishedBasement = true;
                            else
                                House.FinishedBasement = false;
                        }
                        catch (FormatException)
                        {
                           Console.WriteLine("Invalid Basement Answer");
                        }
                        break;
    
                    case PropertyType.Townhouse:
                        Type = PropertyType.Townhouse;
                        try
                        {
                            Console.Write("How many stories (levels)?                ");
                            House.Stories = short.Parse(Console.ReadLine());
                        }
                        catch (FormatException ex)
                        {
                           Console.WriteLine(ex.Message);
                        }
                        Console.Write("Does it have an indoor car garage (y/n)?      ");
                        answer = Console.ReadLine();
                        if ((answer == "y") || (answer == "Y"))
                            House.IndoorGarage = true;
                        else
                            House.IndoorGarage = false;
    
                        Console.Write("Is the basement finished(y/n):           ");
                        answer = Console.ReadLine();
                        if ((answer == "y") || (answer == "Y"))
                            House.FinishedBasement = true;
                        else
                            House.FinishedBasement = false;
                        break;
    
                    case PropertyType.Condominium:
                        Type = PropertyType.Condominium;
                        Console.Write("Is the building handicap accessible (y/n)?    ");
                        answer = Console.ReadLine();
                        if ((answer == "y") || (answer == "Y"))
                            Condominium.HandicapAccessible = true;
                        else
                            Condominium.HandicapAccessible = false;
                        break;
    
                    default:
                        Type = PropertyType.Unknown;
                        break;
                }
    
                try
                {
                    Console.Write("How many bedrooms?                                ");
                    Residence.Bedrooms = int.Parse(Console.ReadLine());
                }
                catch (FormatException ex)
                {
                   Console.WriteLine(ex.Message);
                }
                try
                {
                    Console.Write("How many bathrooms?                               ");
                    Residence.Bathrooms = double.Parse(Console.ReadLine());
                }
                catch (FormatException ex)
                {
                   Console.WriteLine(ex.Message);
                }
                try
                {
                    Console.Write("In what year was the house built?                 ");
                    Residence.YearBuilt = int.Parse(Console.ReadLine());
                }
                catch (FormatException ex)
                {
                   Console.WriteLine(ex.Message);
                }
                try
                {
                    Console.Write("What is the current market value of the property? ");
                    Residence.MarketValue = double.Parse(Console.ReadLine());
                }
                catch (FormatException ex)
                {
                   Console.WriteLine(ex.Message);
                }
            }
    
            public void ShowProperty()
            {
                Console.Title = "Altair Realtors - Property Creation";
                Console.WriteLine("========================================");
                Console.WriteLine(" =//=//=     Altair Realtors     =//=//=");
                Console.WriteLine("-=-=-=-    Properties Listing    -=-=-=-");
                Console.WriteLine("----------------------------------------");
                Console.WriteLine("Property #:            {0}", Residence.PropertyNumber);
                Console.WriteLine("Property Type:         {0}", Type);
    
                switch (Type)
                {
                    case PropertyType.SingleFamily:
                    case PropertyType.Townhouse:
                        Type = PropertyType.SingleFamily;
                       Console.WriteLine("Stories:               {0}",
                            House.Stories);
                       Console.WriteLine("Has Indoor Car Garage: {0}",
                            House.IndoorGarage);
                       Console.WriteLine("Finished Basement:     {0}",
                            House.FinishedBasement);
                        break;
    
                    case PropertyType.Condominium:
                       Console.WriteLine("Handicapped Accessible Building: {0}",
                            Condominium.HandicapAccessible);
                        break;
                }
    
                Console.WriteLine("Condition:             {0}", Residence.Condition);
                Console.WriteLine("Bedrooms:              {0}", Residence.Bedrooms);
                Console.WriteLine("Bathrooms:             {0}", Residence.Bathrooms);
                Console.WriteLine("Year Built:            {0}", Residence.YearBuilt);
                Console.WriteLine("Market Value:          {0:C}", Residence.MarketValue);
                Console.WriteLine("========================================");
            }
        }
    }
  23. To create a new file, on the main menu, click Project -> Add Class...
  24. Type RealEstate
  25. Click Add
  26. Change the document as follows:
    using static System.Console;
    
    namespace RealEstate1
    {
        public class RealEstate
        {
            public static int Main()
            {
                Title = "Altair Realtors";
                PropertyListing listing = new PropertyListing();
    
                listing.CreateListing();
                Clear();
                listing.ShowProperty();
                
                return 0;
            }
    
        }
    }
  27. To execute the application, on the main menu, click Debug -> Start Debugging
  28. Enter the values as follows (press Enter after each):
     =//= Altair Realtors =//=
    --------------------------------------------------------------
    -=- Property Creation -=-
    Types of Properties
    1. Single Family
    2. Townhouse
    3. Condominium
    4. Don't Know
    Enter Type of property:                           1
    --------------------------------------------------------------
    Properties Conditions
    1. Excellent
    2. Good (may need minor repair)
    3. Needs Maintenance
    4. In Bad Shape (property needs major maintenance or rebuild)
    Enter Property Condition:                         3
    --------------------------------------------------------------
    How many stories (levels)?                        -2
    Does it have an indoor car garage (y/n):          g
    Is the basement finished(y/n):                    m
    How many bedrooms?                                -5
    How many bathrooms?                               93057
    In what year was the house built?                 3684
    What is the current market value of the property? 8736846
  29. Press Enter
    ========================================
     =//=//=     Altair Realtors     =//=//=
    -=-=-=-    Properties Listing    -=-=-=-
    ----------------------------------------
    Property #:            861478
    Property Type:         SingleFamily
    Stories:               -2
    Has Indoor Car Garage: False
    Finished Basement:     False
    Condition:             NeedsMaintenance
    Bedrooms:              -5
    Bathrooms:             93057
    Year Built:            3684
    Market Value:          $8,736,846.00
    ========================================
    Press any key to continue . . .
  30. Press Enter to close the DOS window and return to your programming environment

Throwing an Exception

When a bad behavior occurs in your application, the program is said to throw an exception. Your job is to know, as much as possible, when and why this would happen. In the previous lesson and in the above section, we saw that, when an application throws an exception, you could display your own message. To effectively address a particular exception, you need to identify the (exact, if possible) section of code where the exception would occur and you should know why the error would be produced. After identifying the area in code where an exception is likely to occur, you can further customize the behavior of your application.

To customize the throwing of an exception, in the section of code where you are anticipating the error, type the throw keyword followed by a new instance of the Exception class (or one of its derived classes) using the constructor that takes a string. Here is an example:

using System;

public class Exercise
{
    public static int Main()
    {
        double operand1, operand2;
        double Result = 0.00;
        string Operator;

        Console.WriteLine(
	    "This program allows you to perform an operation on two numbers");

        try
        {
            Console.Write("Enter a number: ");
            operand1 = double.Parse(Console.ReadLine());
            Console.Write("Enter an operator: ");
            Operator = Console.ReadLine();
            Console.Write("Enter a number: ");
            operand2 = double.Parse(Console.ReadLine());

            if (Operator != "+" && Operator != "-" && Operator != "*" && Operator != "/")
                throw new Exception(Operator.ToString());
            switch (Operator)
            {
                case "+":
                    Result = operand1 + operand2;
                    break;

                case "-":
                    Result = operand1 - operand2;
                    break;

                case "*":
                    Result = operand1 * operand2;
                    break;

                case "/":
                    Result = operand1 / operand2;
                    break;

                default:
                    Console.WriteLine("Bad Operation");
                    break;
            }

	    Console.WriteLine("{0} {1} {2} = {3}", operand1, Operator, operand2, Result);
        }
        catch (Exception ex)
        {
	    Console.WriteLine("Operation Error: {0} is not a valid operator", ex.Message);
        }

        return 0;
    }
}

Here is an example of running the program:

This program allows you to perform an operation on two numbers
Enter a number: 124.55
Enter an operator: &
Enter a number: 36.85

Operation Error: & is not a valid operator
Press any key to continue . . .

ApplicationPractical Learning: Throwing an Exception

  1. Access the PropertyListing.cs file
  2. To throw some exceptions, change the document as follows:
    using System;
    
    namespace RealEstate1
    {
        public enum PropertyType
        {
            Unknown,
            SingleFamily,
            Townhouse,
            Condominium
        }
    
        public class PropertyListing
        {
            public Residence Residence { get; set; }
            public House House { get; set; }
            public Condominium Condominium { get; set; }
            public PropertyType Type { get; set; }
    
            public PropertyListing()
            {
                Residence = new Residence();
                House = new House();
                Condominium = new Condominium();
            }
    
            public void CreateListing()
            {
                string answer = "n";
                int propType = 1;
                int condition = 1;
    
                Console.Title = "Altair Realtors - Property Creation";
                Console.WriteLine(" =//= Altair Realtors =//=");
                Console.WriteLine("--------------------------------------------------------------");
                Console.WriteLine("-=- Property Creation -=-");
                try
                {
                    Console.WriteLine("Types of Properties");
                    Console.WriteLine("1. Single Family");
                    Console.WriteLine("2. Townhouse");
                    Console.WriteLine("3. Condominium");
                    Console.WriteLine("4. Don't Know");
                    Console.Write("Enter Type of property:                           ");
                    propType = short.Parse(Console.ReadLine());
                }
                catch (FormatException ex)
                {
                    Console.WriteLine(ex.Message);
                }
    
                Random rndNumber = new Random();
                Residence.PropertyNumber = rndNumber.Next(100001, 999999);
    
                Console.WriteLine("--------------------------------------------------------------");
                try
                {
                    Console.WriteLine("Properties Conditions");
                    Console.WriteLine("1. Excellent");
                    Console.WriteLine("2. Good (may need minor repair)");
                    Console.WriteLine("3. Needs Maintenance");
                    Console.Write("4. In Bad Shape (property needs ");
                    Console.WriteLine("major maintenance or rebuild)");
                    Console.Write("Enter Property Condition:                         ");
                    condition = short.Parse(Console.ReadLine());
                }
                catch (FormatException ex)
                {
                    Console.WriteLine(ex.Message);
                }
    
                if (condition == 1)
                    Residence.Condition = PropertyCondition.Excellent;
                else if (condition == 2)
                    Residence.Condition = PropertyCondition.Good;
                else if (condition == 3)
                    Residence.Condition = PropertyCondition.NeedsMaintenance;
                else if (condition == 4)
                    Residence.Condition = PropertyCondition.BadShape;
                else
                    Residence.Condition = PropertyCondition.Unknown;
    
                Console.WriteLine("--------------------------------------------------------------");
                switch ((PropertyType)propType)
                {
                    case PropertyType.SingleFamily:
                        Type = PropertyType.SingleFamily;
    
                        try
                        {
                            Console.Write("How many stories (levels)?                        ");
                            House.Stories = short.Parse(Console.ReadLine());
    
                            if (House.Stories < 1)
                            {
                                House.Stories = 1;
                                Console.BackgroundColor = ConsoleColor.DarkRed;
                                Console.ForegroundColor = ConsoleColor.White;
    
                                throw new OverflowException(" - - The number of stories (of a single family house) must be positive. - -");
                            }
                        }
                        catch (OverflowException ex)
                        {
                            Console.WriteLine(ex.Message);
                        }
    
                        Console.ResetColor();
    
                        try
                        {
                            Console.Write("Does it have an indoor car garage (y/n):          ");
                            answer = Console.ReadLine();
                            if ((answer == "y") || (answer == "Y"))
                                House.IndoorGarage = true;
                            else
                                House.IndoorGarage = false;
                        }
                        catch (FormatException)
                        {
                            Console.WriteLine("Invalid Indoor Car Garage Answer");
                        }
                        try
                        {
                            Console.Write("Is the basement finished(y/n):                    ");
                            answer = Console.ReadLine();
                            if ((answer == "y") || (answer == "Y"))
                                House.FinishedBasement = true;
                            else
                                House.FinishedBasement = false;
                        }
                        catch (FormatException)
                        {
                            Console.WriteLine("Invalid Basement Answer");
                        }
                        break;
    
                    case PropertyType.Townhouse:
                        Type = PropertyType.Townhouse;
                        try
                        {
                            Console.Write("How many stories (levels)?                        ");
                            House.Stories = short.Parse(Console.ReadLine());
    
                            if (House.Stories < 1)
                            {
                                House.Stories = 1;
                                Console.BackgroundColor = ConsoleColor.DarkRed;
                                Console.ForegroundColor = ConsoleColor.White;
    
                                throw new OverflowException(" - - The number of stories (of a townhouse) must be positive. - -");
                            }
                        }
                        catch (OverflowException ex)
                        {
                            Console.WriteLine(ex.Message);
                        }
    
                        Console.ResetColor();
    
                        Console.Write("Does it have an indoor car garage (y/n)?           ");
                        answer = Console.ReadLine();
                        if ((answer == "y") || (answer == "Y"))
                            House.IndoorGarage = true;
                        else
                            House.IndoorGarage = false;
    
                        Console.Write("Is the basement finished(y/n):                     ");
                        answer = Console.ReadLine();
                        if ((answer == "y") || (answer == "Y"))
                            House.FinishedBasement = true;
                        else
                            House.FinishedBasement = false;
                        break;
    
                    case PropertyType.Condominium:
                        Type = PropertyType.Condominium;
                        Console.Write("Is the building handicap accessible (y/n)?    ");
                        answer = Console.ReadLine();
                        if ((answer == "y") || (answer == "Y"))
                            Condominium.HandicapAccessible = true;
                        else
                            Condominium.HandicapAccessible = false;
                        break;
    
                    default:
                        Type = PropertyType.Unknown;
                        break;
                }
    
                try
                {
                    Console.Write("How many bedrooms?                                 ");
                    Residence.Bedrooms = int.Parse(Console.ReadLine());
                }
                catch (FormatException ex)
                {
                    Console.WriteLine(ex.Message);
                }
                try
                {
                    Console.Write("How many bathrooms?                                ");
                    Residence.Bathrooms = double.Parse(Console.ReadLine());
                }
                catch (FormatException ex)
                {
                    Console.WriteLine(ex.Message);
                }
                try
                {
                    Console.Write("In what year was the house built?                  ");
                    Residence.YearBuilt = int.Parse(Console.ReadLine());
                }
                catch (FormatException ex)
                {
                    Console.WriteLine(ex.Message);
                }
                try
                {
                    Console.Write("What is the current market value of the property?  ");
                    Residence.MarketValue = double.Parse(Console.ReadLine());
                }
                catch (FormatException ex)
                {
                    Console.WriteLine(ex.Message);
                }
            }
    
            public void ShowProperty()
            {
                Console.Title = "Altair Realtors - Property Creation";
                Console.WriteLine("========================================");
                Console.WriteLine(" =//=//=     Altair Realtors     =//=//=");
                Console.WriteLine("-=-=-=-    Properties Listing    -=-=-=-");
                Console.WriteLine("----------------------------------------");
                Console.WriteLine("Property #:            {0}", Residence.PropertyNumber);
                Console.WriteLine("Property Type:         {0}", Type);
    
                switch (Type)
                {
                    case PropertyType.SingleFamily:
                    case PropertyType.Townhouse:
                        Type = PropertyType.SingleFamily;
                        Console.WriteLine("Stories:               {0}",
                             House.Stories);
                        Console.WriteLine("Has Indoor Car Garage: {0}",
                             House.IndoorGarage);
                        Console.WriteLine("Finished Basement:     {0}",
                             House.FinishedBasement);
                        break;
    
                    case PropertyType.Condominium:
                        Console.WriteLine("Handicapped Accessible Building: {0}",
                             Condominium.HandicapAccessible);
                        break;
                }
    
                Console.WriteLine("Condition:             {0}", Residence.Condition);
                Console.WriteLine("Bedrooms:              {0}", Residence.Bedrooms);
                Console.WriteLine("Bathrooms:             {0}", Residence.Bathrooms);
                Console.WriteLine("Year Built:            {0}", Residence.YearBuilt);
                Console.WriteLine("Market Value:          {0:C}", Residence.MarketValue);
                Console.WriteLine("========================================");
            }
        }
    }
  3. To execute the application, on the main menu, click Debug -> Start Debugging
  4. Enter the values as follows:

    Exception Handling

  5. Press Enter
    ========================================
     =//=//=     Altair Realtors     =//=//=
    -=-=-=-    Properties Listing    -=-=-=-
    ----------------------------------------
    Property #:            200251
    Property Type:         Townhouse
    Stories:               1
    Has Indoor Car Garage: False
    Finished Basement:     False
    Condition:             NeedsMaintenance
    Bedrooms:              -4
    Bathrooms:             -2
    Year Built:            30958
    Market Value:          $5.00
    ========================================
    Press any key to continue . . .
  6. Press Enter to close the DOS window and return to your programming environment

Catching Various Exceptions

In the examples above, 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 method with numerous or complex operations and requests can also produce different types of errors. With such a type of program, 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 used would be:

try {
	// Code to Try
}
catch(Arg1)
{
	// One Exception
}
catch(Arg2)
{
	// Another Exception
}

The compiler would proceed in a top-down:

  1. Following the normal flow of the program, the compiler enters the try block
  2. If no exception occurs in the try block, the rest of the try block is executed
    If an exception occurs in the try block, the compiler registers the type of error that occurred. If there is a throw line, the compiler registers it also:
    1. The compiler gets out of the try section
    2. The compiler examines the first catch. If the first catch matches the thrown error, that catch section executes and the exception handling routine may seize. If the first catch section doesn't match the thrown error, the compiler proceeds with the next catch section
    3. The compiler checks the next match, if any, and proceeds as in the first catch section. This continues until the compiler finds a catch section that matches the thrown error
    4. If one of the catches matches the thrown error, its body executes. If no catch matches the thrown error, the compiler calls the Exception class and uses the default message

Multiple catches are written if or when a try block is expected to throw different types of errors. Once again, consider the previous program. That program works fine as long as the user types a valid sequence of values made of a number, a valid arithmetic operator, and a number. Anything else, such as an invalid number, an unexpected operator, or a wrong sequence (such as a number then another number instead of an operator), would cause an error. Obviously various bad things could happen when this program is running. To handle the exceptions that this program could produce, you can start with the most likely problem that would occur. Trusting that a user is able to provide the two numbers that are requested, it is possible that a user would type an invalid operator. For example, for this program we will perform only the addition (+), the subtraction(-), the multiplication(*), and the division(/). Therefore, we will first validate the operator. This can be done as follows:

using System;

public class Program
{
    public static int Main()
    {
        double operand1, operand2;
        double result = 0.00;
        string operator;

	    Console.WriteLine("This program allows you to perform an operation on two numbers");

        try
        {
            Console.Write("Enter a number: ");
            operand1 = double.Parse(Console.ReadLine());
            Console.Write("Enter an operator: ");
            operator = Console.ReadLine();
            Console.Write("Enter a number: ");
            operand2 = double.Parse(Console.ReadLine());

            if (operator != "+" &&
                operator != "-" &&
                operator != "*" &&
                operator != "/")
                throw new Exception(operator.ToString());

            switch (operator)
            {
                case "+":
                    result = operand1 + operand2;
                    break;

                case "-":
                    result = operand1 - operand2;
                    break;

                case "*":
                    result = operand1 * operand2;
                    break;

                case "/":
                    result = operand1 / operand2;
                    break;

                default:
                    Console.WriteLine("Bad Operation");
                    break;
            }

	        Console.WriteLine("{0} {1} {2} = {3}", operand1, operator, operand2, result);
        }
        catch (Exception ex)
        {
	        Console.WriteLine("Operation Error: {0} is not a valid operator", ex.Message);
        }

        return 0;
    }
}

When this program runs, if the user provides a valid number followed by a wrong operator, we call the Exception(string message) constructor and pass it a string converted from the character that was typed.

Imagine that the user wants to perform a division. You need to tell the compiler what to do if the user enters the denominator as 0 (or 0.00). If this happens, probably the best option is to display a message and get out. Fortunately, the .NET Framework provides the DivideByZeroException class to deal with an exception caused by division by zero. As done with the message passed to the Exception class, you can compose your own message and pass it to the DivideByZeroException(string message) constructor.

Here is an example that catches two types of exceptions:

using System;

public class Program
{
    public static int Main()
    {
        double operand1, operand2;
        double result = 0.00;
        char operator;

	    Console.WriteLine("This program allows you to perform an operation on two numbers");

        try
        {
            Console.Write("Enter a number: ");
            operand1 = double.Parse(Console.ReadLine());
            Console.Write("Enter an operator: ");
            operator = Console.ReadLine();
            Console.Write("Enter a number: ");
            operand2 = double.Parse(Console.ReadLine());

            if (operator != "+" &&
                operator != "-" &&
                operator != "*" &&
                operator != "/")
                throw new Exception(operator.ToString());

            if (operator == "/") if (operand2 == 0)
                throw new DivideByZeroException("Division by zero is not allowed");

            switch(operator)
            {
                case "+":
                    result = operand1 + operand2;
                    break;

                case "-":
                    Result = operand1 - operand2;
                    break;

                case "*":
                    Result = operand1 * operand2;
                    break;

                case "/":
                    Result = operand1 / operand2;
                    break;

                default:
                    Console.WriteLine("Bad Operation");
                    break;
            }
            	
     	    Console.WriteLine("{0} {1} {2} = {3}", operand1, operator, operand2, result);
        }
        catch (DivideByZeroException ex)
        {
            Console.WriteLine(ex.Message);
        }
        catch (Exception ex)
        {
    	    Console.WriteLine("Operation Error: {0} is not a valid operator", ex.Message);
        }

        return 0;
    }
}

When running this program, if the user types a wrong operator, the compiler gets out of the try block and looks for a catch that takes an Exception as argument. It finds the second and executes it. If the user enters the right values (a number, an operator, and another number), then the compiler finds out if the operator entered was a forward slash "/" used to perform a division. If the user wants to perform a division, the compiler finds out if the second operand, the denominator, is 0. If it is, we create a DivideByZeroException instance and pass our own message to it. Based on this exception, the compiler gets out of the try block and starts looking for a catch block that takes a DivideByZeroException argument. It finds it in the first catch. Therefore, the compiler executes it.

ApplicationPractical Learning: Catching Various Exceptions

  1. Change the PropertyListing.cs file as follows:
    using System;
    
    namespace RealEstate1
    {
        public enum PropertyType
        {
            Unknown,
            SingleFamily,
            Townhouse,
            Condominium
        }
    
        public class PropertyListing
        {
            public Residence Residence { get; set; }
            public House House { get; set; }
            public Condominium Condominium { get; set; }
            public PropertyType Type { get; set; }
    
            public PropertyListing()
            {
                Residence = new Residence();
                House = new House();
                Condominium = new Condominium();
            }
    
            public void CreateListing()
            {
                string answer = "n";
                int propType = 1;
                int condition = 1;
    
                Console.Title = "Altair Realtors - Property Creation";
                Console.WriteLine(" =//= Altair Realtors =//=");
                Console.WriteLine("--------------------------------------------------------------");
                Console.WriteLine("-=- Property Creation -=-");
                try
                {
                    Console.WriteLine("Types of Properties");
                    Console.WriteLine("1. Single Family");
                    Console.WriteLine("2. Townhouse");
                    Console.WriteLine("3. Condominium");
                    Console.WriteLine("4. Don't Know");
                    Console.Write("Enter Type of property:                           ");
                    propType = short.Parse(Console.ReadLine());
                }
                catch (FormatException)
                {
                    Console.WriteLine("The value you entered is not a valid number");
                }
                catch (Exception)
                {
                    Console.WriteLine("Something bad happened and we don't like it");
                }
    
                Random rndNumber = new Random();
                Residence.PropertyNumber = rndNumber.Next(100001, 999999);
    
                Console.WriteLine("--------------------------------------------------------------");
                try
                {
                    Console.WriteLine("Properties Conditions");
                    Console.WriteLine("1. Excellent");
                    Console.WriteLine("2. Good (may need minor repair)");
                    Console.WriteLine("3. Needs Maintenance");
                    Console.Write("4. In Bad Shape (property needs ");
                    Console.WriteLine("major maintenance or rebuild)");
                    Console.Write("Enter Property Condition:                         ");
                    condition = short.Parse(Console.ReadLine());
                }
                catch (FormatException)
                {
                    Console.WriteLine("The value you typed for the property condition is not good");
                }
                catch (Exception)
                {
                    Console.WriteLine("Something unacceptable has just happened");
                }
    
                if (condition == 1)
                    Residence.Condition = PropertyCondition.Excellent;
                else if (condition == 2)
                    Residence.Condition = PropertyCondition.Good;
                else if (condition == 3)
                    Residence.Condition = PropertyCondition.NeedsMaintenance;
                else if (condition == 4)
                    Residence.Condition = PropertyCondition.BadShape;
                else
                    Residence.Condition = PropertyCondition.Unknown;
    
                Console.WriteLine("--------------------------------------------------------------");
                switch ((PropertyType)propType)
                {
                    case PropertyType.SingleFamily:
                        Type = PropertyType.SingleFamily;
    
                        try
                        {
                            Console.Write("How many stories (levels)?                        ");
                            House.Stories = short.Parse(Console.ReadLine());
    
                            if (House.Stories < 1)
                            {
                                House.Stories = 1;
                                Console.BackgroundColor = ConsoleColor.DarkRed;
                                Console.ForegroundColor = ConsoleColor.White;
    
                                throw new OverflowException(" - - The number of stories (of a single family house) must be positive. - -");
                            }
                        }
                        catch (OverflowException ex)
                        {
                            Console.WriteLine(ex.Message);
                        }
                        catch (FormatException)
                        {
                            Console.WriteLine("The number you entered for the stories is not allowed");
                        }
                        catch (Exception)
                        {
                            Console.WriteLine("This is one of those abnormal behaviors");
                        }
    
                        Console.ResetColor();
    
                        try
                        {
                            Console.Write("Does it have an indoor car garage (y/n):          ");
                            answer = Console.ReadLine();
                            if ((answer == "y") || (answer == "Y"))
                                House.IndoorGarage = true;
                            else
                                House.IndoorGarage = false;
                        }
                        catch (FormatException)
                        {
                            Console.WriteLine("Invalid Indoor Car Garage Answer");
                        }
                        try
                        {
                            Console.Write("Is the basement finished(y/n):                    ");
                            answer = Console.ReadLine();
                            if ((answer == "y") || (answer == "Y"))
                                House.FinishedBasement = true;
                            else
                                House.FinishedBasement = false;
                        }
                        catch (FormatException)
                        {
                            Console.WriteLine("Invalid Basement Answer");
                        }
                        break;
    
                    case PropertyType.Townhouse:
                        Type = PropertyType.Townhouse;
                        try
                        {
                            Console.Write("How many stories (levels)?                        ");
                            House.Stories = short.Parse(Console.ReadLine());
    
                            if (House.Stories < 1)
                            {
                                House.Stories = 1;
                                Console.BackgroundColor = ConsoleColor.DarkRed;
                                Console.ForegroundColor = ConsoleColor.White;
    
                                throw new OverflowException(" - - The number of stories (of a townhouse) must be positive. - -");
                            }
                        }
                        catch (OverflowException ex)
                        {
                            Console.WriteLine(ex.Message);
                        }
                        catch (FormatException)
                        {
                            Console.WriteLine("The number you entered for the stories is not allowed");
                        }
                        catch (Exception)
                        {
                            Console.WriteLine("This is one of those abnormal behaviors");
                        }
    
                        Console.ResetColor();
    
                        Console.Write("Does it have an indoor car garage (y/n)?           ");
                        answer = Console.ReadLine();
                        if ((answer == "y") || (answer == "Y"))
                            House.IndoorGarage = true;
                        else
                            House.IndoorGarage = false;
    
                        Console.Write("Is the basement finished(y/n):                     ");
                        answer = Console.ReadLine();
                        if ((answer == "y") || (answer == "Y"))
                            House.FinishedBasement = true;
                        else
                            House.FinishedBasement = false;
                        break;
    
                    case PropertyType.Condominium:
                        Type = PropertyType.Condominium;
                        Console.Write("Is the building handicap accessible (y/n)?    ");
                        answer = Console.ReadLine();
                        if ((answer == "y") || (answer == "Y"))
                            Condominium.HandicapAccessible = true;
                        else
                            Condominium.HandicapAccessible = false;
                        break;
    
                    default:
                        Type = PropertyType.Unknown;
                        break;
                }
    
                try
                {
                    Console.Write("How many bedrooms?                                ");
                    Residence.Bedrooms = int.Parse(Console.ReadLine());
                }
                catch (FormatException)
                {
                    Console.BackgroundColor = ConsoleColor.DarkRed;
                    Console.ForegroundColor = ConsoleColor.White;
                    Console.WriteLine("The value you entered for the number of bedrooms is not acceptable");
                }
                catch (Exception)
                {
                    Console.WriteLine("The program has decided to stop");
                }
    
                Console.ResetColor();
    
                try
                {
                    Console.Write("How many bathrooms?                                ");
                    Residence.Bathrooms = double.Parse(Console.ReadLine());
                }
                catch (FormatException)
                {
                    Console.BackgroundColor = ConsoleColor.DarkRed;
                    Console.ForegroundColor = ConsoleColor.White;
                    Console.WriteLine("The value you decided to enter for the bathrooms is rejected.");
                }
                catch (Exception)
                {
                    Console.WriteLine("The computer doesn't like what is going on");
                }
    
                Console.ResetColor();
    
                try
                {
                    Console.Write("In what year was the house built?                  ");
                    Residence.YearBuilt = int.Parse(Console.ReadLine());
                }
                catch (FormatException)
                {
                    Console.BackgroundColor = ConsoleColor.DarkRed;
                    Console.ForegroundColor = ConsoleColor.White;
                    Console.WriteLine("You didn't enter a valid number for the year built.");
                }
                catch (Exception)
                {
                    Console.WriteLine("Whatever, whatever, whatever");
                }
    
                Console.ResetColor();
    
                try
                {
                    Console.Write("What is the current market value of the property?  ");
                    Residence.MarketValue = double.Parse(Console.ReadLine());
                }
                catch (FormatException)
                {
                    Console.BackgroundColor = ConsoleColor.DarkRed;
                    Console.ForegroundColor = ConsoleColor.White;
                    Console.WriteLine("The value of a property must be a good decimal number");
                }
                catch (Exception)
                {
                    Console.WriteLine("This is where the application draws the line: it stops!");
                }
    
                Console.ResetColor();
    
                Console.Write("Thank you for your answers...");
                answer = Console.ReadLine();
            }
    
            public void ShowProperty()
            {
                Console.Title = "Altair Realtors - Property Creation";
                Console.WriteLine("========================================");
                Console.WriteLine(" =//=//=     Altair Realtors     =//=//=");
                Console.WriteLine("-=-=-=-    Properties Listing    -=-=-=-");
                Console.WriteLine("----------------------------------------");
                Console.WriteLine("Property #:            {0}", Residence.PropertyNumber);
                Console.WriteLine("Property Type:         {0}", Type);
    
                switch (Type)
                {
                    case PropertyType.SingleFamily:
                    case PropertyType.Townhouse:
                        Type = PropertyType.SingleFamily;
                        Console.WriteLine("Stories:               {0}",
                             House.Stories);
                        Console.WriteLine("Has Indoor Car Garage: {0}",
                             House.IndoorGarage);
                        Console.WriteLine("Finished Basement:     {0}",
                             House.FinishedBasement);
                        break;
    
                    case PropertyType.Condominium:
                        Console.WriteLine("Handicapped Accessible Building: {0}",
                             Condominium.HandicapAccessible);
                        break;
                }
    
                Console.WriteLine("Condition:             {0}", Residence.Condition);
                Console.WriteLine("Bedrooms:              {0}", Residence.Bedrooms);
                Console.WriteLine("Bathrooms:             {0}", Residence.Bathrooms);
                Console.WriteLine("Year Built:            {0}", Residence.YearBuilt);
                Console.WriteLine("Market Value:          {0:C}", Residence.MarketValue);
                Console.WriteLine("========================================");
            }
        }
    }
  2. To test the application, on the main menu, click Debug -> Start Debugging
  3. Enter the values as follows:

    Exception Handling

  4. Press Enter
    ========================================
     =//=//=     Altair Realtors     =//=//=
    -=-=-=-    Properties Listing    -=-=-=-
    ----------------------------------------
    Property #:            154402
    Property Type:         SingleFamily
    Stories:               1
    Has Indoor Car Garage: True
    Finished Basement:     False
    Condition:             BadShape
    Bedrooms:              0
    Bathrooms:             0
    Year Built:            0
    Market Value:          $0.00
    ========================================
    Press any key to continue . . .
  5. Press Enter to close the DOS window and return to your programming environment

Exception Nesting

The calculator simulator we have studied so far performs a division as one of its assignments. We learned that, to perform any operation, the compiler must first make sure that the user has entered a valid operator. Provided the operator is one of those we are expecting, we also must make sure that the user typed valid numbers. Even if these two criteria are met, it was possible that the user enter 0 for the denominator. The block that is used to check for a non-zero denominator depends on the exception that validates the operators. The exception that could result from a zero denominator depends on the user first entering a valid number for the denominator.

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, or 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(es) clause. To effectively handle the exception, make sure you include an appropriate throw in the try block. Here is an example:

using System;

public class Exercise
{
    public static int Main()
    {
        double operand1, operand2;
        double Result = 0.00;
        string Operator;

        Console.WriteLine("This program allows you to perform an operation on two numbers");

        try
        {
            Console.Write("Enter a number: ");
            operand1 = double.Parse(Console.ReadLine());
            Console.Write("Enter an operator: ");
            Operator = Console.ReadLine();
            Console.Write("Enter a number: ");
            operand2 = double.Parse(Console.ReadLine());

            if (Operator != "+" &&
                Operator != "-" &&
                Operator != "*" &&
                Operator != "/")
                throw new Exception(Operator.ToString());

            switch (Operator)
            {
                case "+":
                    Result = operand1 + operand2;
                    Console.WriteLine("{0} + {1} = {2}", operand1, operand2, Result);
                    break;

                case "-":
                    Result = operand1 - operand2;
                    Console.WriteLine("{0} - {1} = {2}", operand1, operand2, Result);
                    break;

                case "*":
                    Result = operand1 * operand2;
                    Console.WriteLine("{0} * {1} = {2}", operand1, operand2, Result);
                    break;

                case "/":
                    // The following exception is nested in the previous try
                    try
                    {
                        if (operand2 == 0)
                    	   throw new DivideByZeroException("Division by zero is not allowed");

                        Result = operand1 / operand2;
              		Console.WriteLine("{0} / {1} = {2}", operand1, operand2, Result);
                    }
                    catch (DivideByZeroException ex)
                    {
                        Console.WriteLine(ex.Message);
                    }
                    break;
            }
        }
        catch (Exception ex)
        {
	    Console.WriteLine("Operation Error: {0} is not a valid operator", ex.Message);
        }

        return 0;
    }
}

Here is an example of running the program:

This program allows you to perform an operation on two numbers
Enter a number: 324.53
Enter an operator: /
Enter a number: 0
Division by zero is not allowed
Press any key to continue . . .

Exceptions and Methods

One of the most effective techniques used to deal with code is to isolate assignments. We learned this when studying methods of classes. For example, the switch statement that was performing the operations in the "normal" version of our program can be written as follows:

using System;

public class Program
{
    public static int Main()
    {
        double Number1, Number2;
        double Result = 0.00;
        char Operator;

        Console.WriteLine("This program allows you to perform an operation on two numbers");

        try
        {
            Console.WriteLine("To proceed, enter");

            Console.Write("First Number:  ");
            Number1 = double.Parse(Console.ReadLine());

            Console.Write("An Operator (+, -, * or /): ");
            Operator = Console.ReadLine();
            if (Operator != "+" && Operator != "-" &&
                Operator != "*" && Operator != "/")
                throw new Exception(Operator.ToString());

            Console.Write("Second Number: ");
            Number2 = double.Parse(Console.ReadLine());

            if (Operator == "/")
                if (Number2 == 0)
                    throw new DivideByZeroException("Division by zero is not allowed");

            Result = Calculator(Number1, Number2, Operator);
            Console.WriteLine("{0} {1} {2} = {3}", Number1, Operator, Number2, Result);
        }
        catch (FormatException)
        {
            Console.WriteLine("The number you typed is not valid");
        }
        catch (DivideByZeroException ex)
        {
            Console.WriteLine(ex.Message);
        }
        catch (Exception ex)
        {
            Console.WriteLine("Operation Error: {0} is not a valid operator", ex.Message);
        }

        return 0;
    }

    static double Calculator(double Value1, double Value2, char Symbol)
    {
        double Result = 0.00;

        switch (Symbol)
        {
            case "+":
                Result = Value1 + Value2;
                break;

            case "-":
                Result = Value1 - Value2;
                break;

            case "*":
                Result = Value1 * Value2;
                break;

            case "/":
                Result = Value1 / Value2;
                break;
        }

        return Result;
    }
}

Here is one example of running the program:

This program allows you to perform an operation on two numbers
To proceed, enter
First Number:  248.84
An Operator (+, -, * or /): *
Second Number: 57.93

248.84 * 57.93 = 14415.3012
Press any key to continue . . .

Here is another example of running the program:

This program allows you to perform an operation on two numbers
To proceed, enter
First Number:  12.55
An Operator (+, -, * or /): [

Operation Error: [ is not a valid operator
Press any key to continue . . .

You can still use regular methods along with methods that handle exceptions. As done in Main(), any method of a program can take care of its own exceptions that would occur in its body. Here is an example of an exception handled in a method:

using System;

public class Exercise
{
    public static int Main()
    {
        double Number1, Number2;
        double Result = 0.00;
        char Operator;

        Console.WriteLine("This program allows you to perform an operation on two numbers");

        try
        {
            Console.WriteLine("To proceed, enter");

            Console.Write("First Number:  ");
            Number1 = double.Parse(Console.ReadLine());

            Console.Write("An Operator (+, -, * or /): ");
            Operator = Console.ReadLine();
            if (Operator != "+" && Operator != "-" &&
                Operator != "*" && Operator != "/")
                throw new Exception(Operator.ToString());

            Console.Write("Second Number: ");
            Number2 = double.Parse(Console.ReadLine());

            Result = Calculator(Number1, Number2, Operator);
        }
        catch (FormatException)
        {
            Console.WriteLine("The number you typed is not valid");
        }
        catch (Exception ex)
        {
            Console.WriteLine("Operation Error: {0} is not a valid operator", ex.Message);
        }

        return 0;
    }

    static double Calculator(double Value1, double Value2, char Symbol)
    {
        double Result = 0.00;

        switch (Symbol)
        {
            case "+":
                Result = Value1 + Value2;
                Console.WriteLine("{0} + {1} = {2}", Value1, Value2, Result);
                break;

            case "-":
                Result = Value1 - Value2;
                Console.WriteLine("{0} - {1} = {2}", Value1, Value2, Result);
                break;

            case "*":
                Result = Value1 * Value2;
                Console.WriteLine("{0} * {1} = {2}", Value1, Value2, Result);
                break;

            case "/":
                // The following exception is nested in the previous try
                try
                {
                    if (Value2 == 0)
             		throw new DivideByZeroException("Division by zero is not allowed");

                    Result = Value1 / Value2;
                    Console.WriteLine("{0} / {1} = {2}", Value1, Value2, Result);
                }
                catch (DivideByZeroException ex)
                {
                    Console.WriteLine(ex.Message);
                }
                break;
        }

        return Result;
    }
}

Isolating assignments and handing them to method is an important matter in the area of application programming. Consider a program that handles a simple exception such as this one:

using System;

public class Program
{
    public static int Main()
    {
        double Number1, Number2;
        double Result = 0.00;
        char Operator = "/";

	Console.WriteLine("This program allows you to perform a division of two numbers");

        try
        {
            Console.Write("Enter a number: ");
            Number1 = double.Parse(Console.ReadLine());
            Console.Write("Enter a number: ");
            Number2 = double.Parse(Console.ReadLine());

            if (Number2 == 0)
                throw new DivideByZeroException("Division by zero is not allowed");

            Result = Number1 / Number2;
            Console.WriteLine("{0} / {1} = {2}", Number1, Number2, Result);
        }
        catch (DivideByZeroException ex)
        {
            Console.WriteLine(ex.Message);
        }

        return 0;
    }
}

One of the ways you can use methods in exception routines is to have a central method that receives variables, and sends them to other external methods. The external method tests the value of a variable. If an exception occurs, the external method displays or sends a throw. This throw can be picked up by the method that sent the error. Observe the following example that implements this scenario:

using System;

public class Program
{
    public static int Main()
    {
        double Number1, Number2;

	Console.WriteLine("This program allows you to perform a division of two numbers");

	try 
	{
            Console.Write("Enter a number: ");
            Number1 = double.Parse(Console.ReadLine());
            Console.Write("Enter a number: ");
            Number2 = double.Parse(Console.ReadLine());

	    Division(Number1, Number2);
	}
	catch(DivideByZeroException ex)
	{
	    Console.WriteLine(ex.Message);
	}

	return 0;
    }

    static void Division(double a, double b)
    {
	double Result;

	// If an exception occurred,
	if( b == 0 ) // then throw a string to the function caller
		throw new DivideByZeroException("Division by zero is not allowed");

	Result = a / b;
	Console.WriteLine("{0} / {1} = {2}", a, b, Result);
    }
}

In this program, the Division method receives two values that it is asked to perform a division with. The Division method analyzes the second argument that represents the denominator. If this argument is zero, an exception is found and the Division method throws a DivideByZeroException exception.

A method can also be called to perform more than one test to eventually throw more than one exception. Such a method can (and should) be programmed to throw different types of exceptions.

Custom Exceptions

Introduction

As seen in the previous lesson and in the above sections, exception handling is a great part of the .NET Framework. As high as it is supported by various classes of the .NET, it is possible that you want to further customize the handling of exceptions in your application. One way you can do this is to create your own exception class.

Creating an Exceptional Class

The Exception class of the .NET Framework is a great tool for handling exceptions in a C# application. To deal with particular errors, various classes are derived from Exception. If for some reason the Exception class and none of the Exception-based classes fulfills your requirement, you can derive a new class from Exception or from one of the available Exception-based classes.

To derive a class from Exception or from one of its classes, simply follow the rules we reviewed from class inheritance. Here is an example of a class based on Exception:

public class CustomException : Exception 
{
}

There is no real rule to follow as to what class to derive from but it may be a good idea to derive your class from one that already addresses your issue but not the way you want. For example, if you want to create a class that would process numeric values but you think the FormatException class is not doing what you want, you can derive your class from FormatException.

After deriving the class, you can add the necessary members as you see fit. Remember that the primary characteristic of an exception is to present a message to the user. In Exception-based classes, this message is represented by the Message property. Therefore, if you want to prepare a custom message for your class, you can override or new this property. Here is an example:

public class IntegerException : Exception 
{
    public override string Message
    {
        get
        {
            return "The value you entered is not a valid integer";
        }
    }
}

Once you have created and customized your exceptional class, you can use it the same way you would another exception class, such as throwing it. Here is an example

using System;

public class DigitException : Exception
{
    private char c;

    public DigitException(char x)
    {
        c = x;
    }

    public override string Message
    {
        get
        {
            return "The character you entered is not a valid digit";
        }
    }
}

class Program
{
    static int Main()
    {
        try
        {
            string chNumber = "0";

            Console.Write("Enter a digit (0 to 9): ");
            chNumber = Console.ReadLine();

            if ((chNumber != "0") &&
                (chNumber != "1") &&
                (chNumber != "2") &&
                (chNumber != "3") &&
                (chNumber != "4") &&
                (chNumber != "5") &&
                (chNumber != "6") &&
                (chNumber != "7") &&
                (chNumber != "8") &&
                (chNumber != "9"))
                 throw new DigitException(chNumber);
           
            Console.WriteLine("Number: {0}", chNumber);
        }
        catch (DigitException ex)
        {
            Console.WriteLine(ex.Message);
        }
        catch (FormatException ex)
        {
            Console.WriteLine(ex.Message);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }

        return 0;
    }
}

Here is an example of running the program:

Enter a digit (0 to 9): 8
Number: 8

Press any key to continue . . .

Here is another example of running the program:

Enter a digit (0 to 9): w
The character you entered is not a valid digit
Press any key to continue . . .

ApplicationPractical Learning: Ending the Lesson


Previous Copyright © 2008-2019, FunctionX Home