Exception handling in C# Programming with Example

Exceptions are an important aspect of C# programming because they allow developers to handle unexpected errors and prevent program crashes. In this article, we will learn how to handle exceptions in C# with proper steps and examples.

Exception Handling

Understanding Exceptions in C#

What are exceptions & exception handling in C#.net?
A C # exception is an unusual condition or error that occurs during program execution. Bad login, network problem, file system error etc. Exception handling is the process of handling and handling these exceptions to ensure the normal operation of the application.

Exception Handling in C#

1. Using try-catch Blocks

The try block is the primary exception handling mechanism in C#. It allows you to test a block of code and catch all exceptions that occur in that block.

try out
{
    // Code that can cause an exception
    int result = 10/0; // This will throw a DivideByZeroException
}
catch ( DivideByZeroException ex );
{
    // Throws an exception
    Console.WriteLine("error: " + ex.Message);
}

In this example, the try block tries to perform a division operation, which may generate a DivideByZeroException. The catch block catches the exception and handles it by printing an error message.

2. Handling Multiple Exceptions

You can catch and handle multiple types of exceptions using multiple catch blocks or a single block with multiple exception types.

try out
{
    // Code that can cause an exception
    int [] number = { 1 , 2 , 3 };
    Console.WriteLine(number[4]); // This will throw an IndexOutOfRangeException
}
catch (IndexOutOfRangeException ex)
{
    // Handle IndexOutOfRangeException
    Console.WriteLine("error: index out of bounds");
}
catch (exception)
{
    // Handle other exceptions
    Console.WriteLine("error: " + ex.Message);
}

In this example, we handle ‘IndexOutOfRangeException’ separately and catch other exceptions using the generic exception block.

3. Finally Block

The last block is used to execute code that should run regardless of an exception or not. This is often used for cleanup operations such as closing files or extracting resources.

using System;

class Program
{
    static void Main()
    {
        try
        {
            // Simulating an exception
            int[] numbers = { 1, 2, 3 };
            Console.WriteLine(numbers[4]); // This will throw an IndexOutOfRangeException
        }
        catch (IndexOutOfRangeException ex)
        {
            Console.WriteLine("Error: Index out of range");
        }
        catch (Exception ex)
        {
            Console.WriteLine("Error: " + ex.Message);
        }
        finally
        {
            Console.WriteLine("Cleanup operations");
        }
    }
}

4. User-defined exceptions

You can create custom exceptions to handle specific situations in your code. These exceptions inherit from the Exception class or any of its derived classes, providing flexibility in error handling and better organization of code.

Here’s how you can create and use user-defined exceptions in C#:

4.1. Creating a User-Defined Exception Class:

using System;

// Define a custom exception class
public class CustomException : Exception
{
    // Constructor with a message parameter
    public CustomException(string message) : base(message)
    {
    }

    // Additional properties or methods can be added as needed
}

4.2. Throwing the Custom Exception:

public class MyClass
{
    public void SomeMethod()
    {
        // Simulate an error condition
        bool errorCondition = true;

        if (errorCondition)
        {
            // Throw the custom exception
            throw new CustomException("An error occurred in SomeMethod.");
        }
    }
}

4.3. Handling the Custom Exception:

try
{
    MyClass obj = new MyClass();
    obj.SomeMethod();
}
catch (CustomException ex)
{
    // Handle the custom exception
    Console.WriteLine($"Custom Exception: {ex.Message}");
}
catch (Exception ex)
{
    // Handle other exceptions
    Console.WriteLine($"Exception: {ex.Message}");
}

In this example:

  • We define a custom exception class CustomException that inherits from Exception.
  • The class includes a constructor that takes a message parameter, allowing us to provide specific error messages when throwing this exception.
  • Inside SomeMethod of MyClass, we check for an error condition and throw a CustomException if the condition is met.
  • In the try-catch block, we catch the CustomException specifically and handle it accordingly.

4.4 Example with Details (Custom Exception):

Let’s say we’re developing a banking application and want to create a custom exception for insufficient funds when withdrawing money. Here’s how it might look:

using System;

// Custom exception for insufficient funds
public class InsufficientFundsException : Exception
{
    public InsufficientFundsException(string message) : base(message)
    {
    }

    // Additional properties or methods can be added as needed
}

public class BankAccount
{
    private decimal balance;

    public BankAccount(decimal initialBalance)
    {
        balance = initialBalance;
    }

    public void Withdraw(decimal amount)
    {
        if (amount > balance)
        {
            throw new InsufficientFundsException("Insufficient funds to withdraw.");
        }

        balance -= amount;
        Console.WriteLine($"Withdrawn: ${amount}, Remaining Balance: ${balance}");
    }
}

class Program
{
    static void Main()
    {
        BankAccount account = new BankAccount(1000);

        try
        {
            account.Withdraw(1500);
        }
        catch (InsufficientFundsException ex)
        {
            Console.WriteLine($"Error: {ex.Message}");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Exception: {ex.Message}");
        }
    }
}

In this example:

  • We define a InsufficientFundsException class for handling insufficient funds during withdrawals.
  • The Withdraw method in BankAccount checks if the withdrawal amount exceeds the balance and throws the custom exception if so.
  • In the Main method, we create a BankAccount instance and attempt to withdraw an amount that exceeds the balance, triggering the custom exception which we then catch and handle.

Best Practices for Exception

  1. Catch Specific Exceptions: Catch specific exceptions as much as possible to handle them correctly.
  2. Use Finally Block: Use finally block for cleanup operations to ensure that resources are freed.
  3. Avoid Empty Catch Blocks: Avoid empty catch blocks as they can hide errors and complicate debugging.
  4. Logging: Exceptions for efficient error tracking and problem diagnosis.
  5. Handle Exceptions at the Correct Level: Handle exceptions at the appropriate level of abstraction (e.g., in exposed methods or higher-level components).
Note: Here, you can checkout our post on How to implement multithreading in C#?

Conclusion:

Exception handling is an essential skill for developers in providing reliable and resilient applications. By following best practices and understanding exception mechanisms, developers can build robust software that can handle errors.

Here, For more information you can refer to the Microsoft online documentation on Exceptions and Exception Handling & Best practices for exceptions.

Leave a Comment

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

Scroll to Top