Exception Handling in C#
Exception handling is used to manage runtime errors gracefully and prevent application crashes.
1. try, catch, finally
- try: Contains code that may throw exceptions.
- catch: Handles exceptions.
- finally: Executes code regardless of exception occurrence (optional).
using System;
class Program
{
static void Main()
{
try
{
int[] numbers = { 1, 2, 3 };
Console.WriteLine(numbers[5]); // Throws IndexOutOfRangeException
}
catch (IndexOutOfRangeException ex)
{
Console.WriteLine("Error: " + ex.Message);
}
finally
{
Console.WriteLine("Finally block executed.");
}
}
}
Output:
Error: Index was outside the bounds of the array.
Finally block executed.
2. throw Keyword
throw is used to manually throw exceptions.
int age = -5;
if (age < 0)
{
throw new ArgumentException("Age cannot be negative");
}
Explanation:
- Throws an exception that can be caught by
catch.
3. Creating Custom Exceptions
You can create user-defined exceptions by inheriting from Exception.
using System;
class NegativeAgeException : Exception
{
public NegativeAgeException(string message) : base(message) { }
}
class Program
{
static void ValidateAge(int age)
{
if (age < 0)
throw new NegativeAgeException("Age cannot be negative");
else
Console.WriteLine("Valid age: " + age);
}
static void Main()
{
try
{
ValidateAge(-10);
}
catch (NegativeAgeException ex)
{
Console.WriteLine("Custom Exception: " + ex.Message);
}
}
}
4. Common Exception Types
| Exception TypeDescription | |
NullReferenceException | Object reference is null |
IndexOutOfRangeException | Index exceeds array or collection bounds |
DivideByZeroException | Division by zero |
FormatException | Invalid format for data conversion |
OverflowException | Value exceeds limits of data type |
InvalidOperationException | Invalid operation performed on object/state |
ArgumentException | Invalid argument passed to method |
FileNotFoundException | File not found |
Example:
string str = null;
try
{
Console.WriteLine(str.Length); // NullReferenceException
}
catch (NullReferenceException ex)
{
Console.WriteLine("Error: " + ex.Message);
}
5. Best Practices in Exception Handling
- Catch specific exceptions first before general exceptions.
- Avoid empty catch blocks; always handle or log.
- Use finally to release resources (files, DB connections).
- Throw exceptions when necessary; avoid suppressing errors.
- Create meaningful custom exceptions for business logic.
- Do not use exceptions for control flow; use them only for exceptional cases.
Example of Proper Usage:
try
{
int result = 10 / int.Parse("0");
}
catch (DivideByZeroException ex)
{
Console.WriteLine("Cannot divide by zero: " + ex.Message);
}
catch (FormatException ex)
{
Console.WriteLine("Invalid number format: " + ex.Message);
}
finally
{
Console.WriteLine("Execution completed.");
}
Summary of Chapter 8:
tryblock contains risky code.catchhandles specific exceptions.finallyexecutes always.throwmanually raises exceptions.- Custom exceptions help define business-specific errors.
- Always follow best practices to write maintainable and safe code.