C# tutorials > Core C# Fundamentals > Exception Handling > What are exception filters and how do they work?
What are exception filters and how do they work?
Exception filters in C# provide a powerful mechanism for selectively handling exceptions. Instead of catching all exceptions of a certain type and then filtering them within the catch block, you can specify a boolean expression that must evaluate to true for the catch block to be executed. This allows for more precise and readable exception handling.
Basic Syntax
The when
keyword is used to introduce the exception filter. ExceptionType
is the type of exception you're trying to catch. FilterExpression
is a boolean expression that determines whether the catch block should be executed. The exception object is available within the filter expression via the variable e
.
try
{
// Code that might throw an exception
}
catch (ExceptionType e) when (FilterExpression)
{
// Handle the exception
}
Simple Example: Filtering by Exception Property
In this example, we catch a DivideByZeroException
only if its message contains the string "Attempted to divide by zero." If the exception doesn't match this criteria, the catch block won't execute, and the exception will propagate up the call stack.
using System;
public class ExceptionFilterExample
{
public static void Main(string[] args)
{
try
{
// Simulate an operation that might throw an exception
PerformOperation(10, 0);
}
catch (DivideByZeroException ex) when (ex.Message.Contains("Attempted to divide by zero."))
{
Console.WriteLine("Caught a DivideByZeroException with a specific message: " + ex.Message);
}
catch (Exception ex)
{
Console.WriteLine("Caught a general exception: " + ex.Message);
}
}
public static void PerformOperation(int a, int b)
{
if (b == 0)
{
throw new DivideByZeroException("Attempted to divide by zero.");
}
int result = a / b;
Console.WriteLine("Result: " + result);
}
}
Concepts Behind the Snippet
Exception filters offer a way to selectively handle exceptions based on their properties or the application's state. This promotes cleaner code by avoiding unnecessary handling within the catch block. The when
keyword is crucial here, defining the boolean condition.
Real-Life Use Case Section
Consider a banking application where an InsufficientFundsException
is thrown when a withdrawal exceeds the account balance. Using exception filters, you can differentiate between small overdrafts (handled by showing a user-friendly error message) and large overdrafts (handled by notifying management for further investigation). This allows different handling strategies for the same exception type.
// Example with a custom exception
public class InsufficientFundsException : Exception
{
public decimal AmountShort { get; set; }
public InsufficientFundsException(string message, decimal amountShort) : base(message)
{
AmountShort = amountShort;
}
}
try
{
// Code that might throw InsufficientFundsException
Withdraw(account, amount);
}
catch (InsufficientFundsException ex) when (ex.AmountShort > 100)
{
Console.WriteLine($"Insufficient funds. Amount short: {ex.AmountShort}. Notifying management.");
// Handle the exception (e.g., notify management)
}
catch (InsufficientFundsException ex)
{
Console.WriteLine($"Insufficient funds. Amount short: {ex.AmountShort}.");
// Handle the exception (e.g., show error to user)
}
Best Practices
Exception
type. This allows for more targeted exception handling.
Interview Tip
When discussing exception filters in an interview, emphasize their role in providing more granular control over exception handling. Highlight the benefits of improved code readability, maintainability, and the ability to handle specific exception scenarios differently within the same catch block. Be prepared to discuss real-world use cases where exception filters provide a valuable solution.
When to Use Them
Use exception filters when you need to handle the same exception type differently based on specific criteria. This avoids having to catch the exception and then use if
statements within the catch block to determine how to handle it. They are particularly useful when dealing with custom exception types and needing to differentiate based on properties of the exception object.
Memory Footprint
The memory footprint of exception filters is generally negligible. The filter expression is evaluated at runtime, and the overhead is typically minimal compared to the cost of throwing and catching an exception. Focus on writing clear and maintainable code rather than micro-optimizing the memory usage of exception filters.
Alternatives
The primary alternative to exception filters is to catch the exception and then use if
statements within the catch block to determine how to handle it. While this approach works, it can lead to less readable and more complex code, especially when multiple conditions need to be checked. Another alternative is to refactor the code to avoid throwing the exception in the first place, but this is not always possible or practical.
Pros
Cons
FAQ
-
Can I use multiple exception filters in a single catch block?
No, you can only have onewhen
clause percatch
block. If you need to handle multiple conditions, you can combine them into a single boolean expression within the filter. -
Are exception filters available in all versions of C#?
Exception filters were introduced in C# 6.0. If you're using an older version of C#, you'll need to use the traditional approach of filtering exceptions within the catch block usingif
statements. -
Can exception filters modify the exception object?
No, exception filters should not have any side effects, including modifying the exception object. Modifying the exception object within the filter can lead to unexpected behavior and make debugging more difficult.