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.
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.
Table of Contents
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 fromException
. - The class includes a constructor that takes a message parameter, allowing us to provide specific error messages when throwing this exception.
- Inside
SomeMethod
ofMyClass
, we check for an error condition and throw aCustomException
if the condition is met. - In the
try-catch
block, we catch theCustomException
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 inBankAccount
checks if the withdrawal amount exceeds the balance and throws the custom exception if so. - In the
Main
method, we create aBankAccount
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
- Catch Specific Exceptions: Catch specific exceptions as much as possible to handle them correctly.
- Use Finally Block: Use
finally
block for cleanup operations to ensure that resources are freed. - Avoid Empty Catch Blocks: Avoid empty catch blocks as they can hide errors and complicate debugging.
- Logging: Exceptions for efficient error tracking and problem diagnosis.
- 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.