C-Sharp | Java | Python | Swift | GO | WPF | Ruby | Scala | F# | JavaScript | SQL | PHP | Angular | HTML
Method A: The code in this method can be thought of as a rethrow—it throws the same exception already being handled.
Method B: This method throws a named exception variable. This is not a rethrow—it throws the same exception but changes the stack trace.
Method C: We can collect information about the exception if needed. Method C creates a new exception.
Tip: We can use a throw statement in this way to implement custom error conditions.
C# program that uses throw statements
using System;
class Program
{
static void Main()
{
// Call method A, method B, and method C.
// ... Comment out the first 1-2 method invocations.
try
{
A();
B();
C(null);
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
static void A()
{
// Rethrow syntax.
try
{
int value = 1 / int.Parse("0");
}
catch
{
throw;
}
}
static void B()
{
// Filtering exception types.
try
{
int value = 1 / int.Parse("0");
}
catch (DivideByZeroException ex)
{
throw ex;
}
}
static void C(string value)
{
// Generate new exception.
if (value == null)
{
throw new ArgumentNullException("value");
}
}
}
Output
System.DivideByZeroException: Attempted to divide by zero.
System.DivideByZeroException: Attempted to divide by zero.
System.ArgumentNullException: Value cannot be null.
Parameter name: value
Methods: In this program, X() uses a rethrow statement. And Y() uses a throw ex statement.
Results: We see in the results that when a rethrow is used, the exception TargetSite is in StringToNumber—an internal method of int.Parse.
int.ParseBut: When a throw ex is used, as in Y(), the exception's TargetSite was modified to the current method Y().
Note: Thanks to Boke Laszlo for pointing out this subtle difference between throw and throw ex.
C# program that tests rethrows
using System;
class Program
{
static void Main()
{
try
{
X();
}
catch (Exception ex)
{
Console.WriteLine(ex.TargetSite);
}
try
{
Y();
}
catch (Exception ex)
{
Console.WriteLine(ex.TargetSite);
}
}
static void X()
{
try
{
int.Parse("?");
}
catch (Exception)
{
throw; // [Rethrow construct]
}
}
static void Y()
{
try
{
int.Parse("?");
}
catch (Exception ex)
{
throw ex; // [Throw captured ex variable]
}
}
}
Output
Void StringToNumber(System.String, ...)
Void Y()
Here: Consider the Test() method. If its argument is null, a new ArgumentException is thrown as part of the null-coalescing statement.
C# program that uses throw expression
using System;
class Program
{
static void Test(string argument)
{
// Use null coalescing operator with throw expression.
// ... If argument is null, throw.
var value = argument ?? throw new ArgumentException("Bad argument");
Console.WriteLine("HERE");
}
static void Main()
{
Test("bird");
Test(null);
}
}
Output
HERE
Unhandled Exception: System.ArgumentException: Bad argument
at Program.Test(String argument) in c:\users\...Program.cs:line 9
at Program.Main() in c:\users\...Program.cs:line 16
Here: The string's length is tested. If it has fewer than 10 characters, an Exception is thrown as part of the ternary.
C# program that uses throw expression in ternary
using System;
class Program
{
static void Main()
{
string test = "bird";
// Throw can be used in ternary.
char tenth = test.Length >= 10 ?
test[9] :
throw new Exception("Not ten characters");
// Not reached.
Console.WriteLine(tenth);
}
}
Output
Unhandled Exception: System.Exception: Not ten characters
at Program.Main() in c:\users\...Program.cs:line 9