C# try/catch

Introduction

The try/catch blocks in C# are used to handle exceptions that occur during the execution of a program. Exceptions are runtime errors that disrupt the normal flow of the program. By using try/catch blocks, you can catch and handle these exceptions gracefully, ensuring that your program continues to run or terminates cleanly.

Basic Structure

Syntax

try
{
    // Code that might throw an exception
}
catch (ExceptionType e)
{
    // Code to handle the exception
}

Example

using System;

namespace TryCatchExample
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                int a = 10;
                int b = 0;
                int result = a / b;
                Console.WriteLine($"Result: {result}");
            }
            catch (DivideByZeroException ex)
            {
                Console.WriteLine("Exception caught: Division by zero is not allowed.");
                Console.WriteLine($"Exception Message: {ex.Message}");
            }
        }
    }
}

Output

Exception caught: Division by zero is not allowed.
Exception Message: Attempted to divide by zero.

Multiple Catch Blocks

You can use multiple catch blocks to handle different types of exceptions.

Example

using System;
using System.IO;

namespace MultipleCatchExample
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                int[] numbers = { 1, 2, 3 };
                Console.WriteLine(numbers[5]); // This will throw IndexOutOfRangeException

                string path = "nonexistentfile.txt";
                string content = File.ReadAllText(path); // This will throw FileNotFoundException
            }
            catch (IndexOutOfRangeException ex)
            {
                Console.WriteLine("Exception caught: Index out of range.");
                Console.WriteLine($"Exception Message: {ex.Message}");
            }
            catch (FileNotFoundException ex)
            {
                Console.WriteLine("Exception caught: File not found.");
                Console.WriteLine($"Exception Message: {ex.Message}");
            }
            catch (Exception ex)
            {
                Console.WriteLine("Exception caught: General exception.");
                Console.WriteLine($"Exception Message: {ex.Message}");
            }
        }
    }
}

Output

Exception caught: Index out of range.
Exception Message: Index was outside the bounds of the array.

Finally Block

The finally block is used to execute a set of statements regardless of whether an exception is thrown or not. It is typically used to clean up resources, such as closing file handles or database connections.

Syntax

try
{
    // Code that might throw an exception
}
catch (ExceptionType e)
{
    // Code to handle the exception
}
finally
{
    // Code that runs regardless of an exception
}

Example

using System;
using System.IO;

namespace FinallyBlockExample
{
    class Program
    {
        static void Main(string[] args)
        {
            StreamReader reader = null;
            try
            {
                reader = new StreamReader("example.txt");
                string content = reader.ReadToEnd();
                Console.WriteLine(content);
            }
            catch (FileNotFoundException ex)
            {
                Console.WriteLine("Exception caught: File not found.");
                Console.WriteLine($"Exception Message: {ex.Message}");
            }
            finally
            {
                if (reader != null)
                {
                    reader.Close();
                    Console.WriteLine("File stream closed.");
                }
            }
        }
    }
}

Output

Exception caught: File not found.
Exception Message: Could not find file 'example.txt'.
File stream closed.

Throwing Exceptions

You can throw exceptions explicitly using the throw keyword. This is useful for handling application-specific error conditions.

Syntax

throw new ExceptionType("Error message");

Example

using System;

namespace ThrowExample
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                ValidateAge(15);
            }
            catch (ArgumentOutOfRangeException ex)
            {
                Console.WriteLine($"Exception caught: {ex.Message}");
            }
        }

        static void ValidateAge(int age)
        {
            if (age < 18)
            {
                throw new ArgumentOutOfRangeException("age", "Age must be at least 18.");
            }
            Console.WriteLine("Age is valid.");
        }
    }
}

Output

Exception caught: Age must be at least 18. (Parameter 'age')

Custom Exceptions

You can create custom exceptions by deriving from the Exception class. This is useful for defining application-specific error conditions.

Example

using System;

namespace CustomExceptionExample
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                ValidateAge(15);
            }
            catch (InvalidAgeException ex)
            {
                Console.WriteLine($"Exception caught: {ex.Message}");
            }
        }

        static void ValidateAge(int age)
        {
            if (age < 18)
            {
                throw new InvalidAgeException("Age must be at least 18.");
            }
            Console.WriteLine("Age is valid.");
        }
    }

    // Custom exception class
    public class InvalidAgeException : Exception
    {
        public InvalidAgeException(string message) : base(message)
        {
        }
    }
}

Output

Exception caught: Age must be at least 18.

Best Practices

  1. Catch Specific Exceptions: Catch specific exceptions rather than using a general Exception catch block.
  2. Log Exceptions: Always log exceptions to help with debugging and monitoring.
  3. Use Finally for Cleanup: Use the finally block to clean up resources like file handles and database connections.
  4. Do Not Swallow Exceptions: Avoid catching exceptions without handling them or logging them.
  5. Custom Exceptions: Create custom exceptions for application-specific error conditions.

Conclusion

Exception handling in C# using try, catch, and finally blocks is a powerful mechanism to handle runtime errors gracefully. By catching and handling exceptions, you can ensure that your application remains robust and continues to operate smoothly. Proper exception handling is crucial for building reliable and maintainable applications.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top