DateTime ToDateTime(IFormatProvider provider) =>
throw new InvalidCastException("Conversion to a DateTime is not supported.");
The
try
statement
You can use the
try
statement in any of the following forms:
try-catch
- to handle exceptions that might occur during execution of the code inside a
try
block,
try-finally
- to specify the code that is executed when control leaves the
try
block, and
try-catch-finally
- as a combination of the preceding two forms.
The
try-catch
statement
Use the
try-catch
statement to handle exceptions that might occur during execution of a code block. Place the code where an exception might occur inside a
try
block. Use a
catch clause
to specify the base type of exceptions you want to handle in the corresponding
catch
block:
var result = Process(-3, 4);
Console.WriteLine($"Processing succeeded: {result}");
catch (ArgumentException e)
Console.WriteLine($"Processing failed: {e.Message}");
You can provide several catch clauses:
var result = await ProcessAsync(-3, 4, cancellationToken);
Console.WriteLine($"Processing succeeded: {result}");
catch (ArgumentException e)
Console.WriteLine($"Processing failed: {e.Message}");
catch (OperationCanceledException)
Console.WriteLine("Processing is cancelled.");
When an exception occurs, catch clauses are examined in the specified order, from top to bottom. At maximum, only one
catch
block is executed for any thrown exception. As the preceding example also shows, you can omit declaration of an exception variable and specify only the exception type in a catch clause. A catch clause without any specified exception type matches any exception and, if present, must be the last catch clause.
If you want to re-throw a caught exception, use the
throw
statement
, as the following example shows:
var result = Process(-3, 4);
Console.WriteLine($"Processing succeeded: {result}");
catch (Exception e)
LogError(e, "Processing failed.");
throw;
throw;
preserves the original stack trace of the exception, which is stored in the
Exception.StackTrace
property. Opposite to that,
throw e;
updates the
StackTrace
property of
e
.
A
when
exception filter
Along with an exception type, you can also specify an exception filter that further examines an exception and decides if the corresponding
catch
block handles that exception. An exception filter is a Boolean expression that follows the
when
keyword, as the following example shows:
var result = Process(-3, 4);
Console.WriteLine($"Processing succeeded: {result}");
catch (Exception e) when (e is ArgumentException || e is DivideByZeroException)
Console.WriteLine($"Processing failed: {e.Message}");
The preceding example uses an exception filter to provide a single
catch
block to handle exceptions of two specified types.
You can provide several
catch
clauses for the same exception type if they distinguish by exception filters. One of those clauses might have no exception filter. If such a clause exists, it must be the last of the clauses that specify that exception type.
If a
catch
clause has an exception filter, it can specify the exception type that is the same as or less derived than an exception type of a
catch
clause that appears after it. For example, if an exception filter is present, a
catch (Exception e)
clause doesn't need to be the last clause.
Exceptions in async and iterator methods
If an exception occurs in an
async function
, it propagates to the caller of the function when you
await
the result of the function, as the following example shows:
public static async Task Run()
Task<int> processing = ProcessAsync(-1);
Console.WriteLine("Launched processing.");
int result = await processing;
Console.WriteLine($"Result: {result}.");
catch (ArgumentException e)
Console.WriteLine($"Processing failed: {e.Message}");
// Output:
// Launched processing.
// Processing failed: Input must be non-negative. (Parameter 'input')
private static async Task<int> ProcessAsync(int input)
if (input < 0)
throw new ArgumentOutOfRangeException(nameof(input), "Input must be non-negative.");
await Task.Delay(500);
return input;
If an exception occurs in an
iterator method
, it propagates to the caller only when the iterator advances to the next element.
The
try-finally
statement
In a
try-finally
statement, the
finally
block is executed when control leaves the
try
block. Control might leave the
try
block as a result of