In C#, you can catch multiple exceptions in a single catch
block using exception filters (introduced in C# 6.0) or by combining separate catch
blocks. Here’s how to handle both scenarios:
1. Using Exception Filters (C# 6.0+)
Use the when
keyword to filter exceptions in a single catch
block.
This preserves the original stack trace and avoids catching unrelated exceptions.
try
{
// Code that may throw exceptions
}
catch (Exception ex) when (ex is FormatException || ex is OverflowException)
{
// Handle FormatException or OverflowException here
Console.WriteLine($"Error: {ex.GetType().Name}");
}
Key Notes:
- The
when
clause acts as a filter for thecatch
block. - You can check for multiple exception types (e.g.,
FormatException
,OverflowException
). - The
ex
variable is of typeException
, so cast it if you need specific properties:
if (ex is FormatException formatEx)
{
Console.WriteLine($"Invalid format: {formatEx.Message}");
}
2. Separate catch
Blocks (Legacy Approach)
For older C# versions (< 6.0), use separate catch
blocks and reuse logic via a helper method.
try
{
// Code that may throw exceptions
}
catch (FormatException ex)
{
HandleError(ex);
}
catch (OverflowException ex)
{
HandleError(ex);
}
// Shared error handler
void HandleError(Exception ex)
{
Console.WriteLine($"Error: {ex.GetType().Name}");
}
3. Catching a Common Base Exception
If the exceptions share a common base type (e.g., ArgumentException
), catch the base type:
try
{
// Code that throws ArgumentNullException or ArgumentOutOfRangeException
}
catch (ArgumentException ex)
{
// Handle all ArgumentException-derived exceptions
Console.WriteLine($"Argument error: {ex.ParamName}");
}
4. Combining Both Approaches
For complex scenarios, mix when
filters and base exceptions:
try
{
// Code that throws exceptions
}
catch (IOException ex) when (ex is FileNotFoundException || ex is DirectoryNotFoundException)
{
// Handle specific IO exceptions
}
catch (Exception ex)
{
// Fallback for all other exceptions
}
Key Considerations
- Order Matters: Place more specific
catch
blocks before general ones (e.g.,FileNotFoundException
beforeIOException
). - Avoid Catching
Exception
Broadly: Only catch exceptions you can handle meaningfully. - Performance: Exception filters (with
when
) are evaluated when the exception is thrown, not when caught.
Example: Parsing User Input
try
{
int num = int.Parse(userInput); // Throws FormatException or OverflowException
}
catch (Exception ex) when (ex is FormatException || ex is OverflowException)
{
Console.WriteLine("Invalid integer format or value too large/small.");
}
Summary
Approach | Use Case | Version Support |
---|---|---|
when Filter | Clean, single-block handling for C# 6.0+ | C# 6.0+ |
Separate catch Blocks | Legacy code or non-shared logic | All versions |
Base Exception | Group related exceptions | All versions |
Use when
filters for modern code to keep your error handling concise and maintainable!