TheDeveloperBlog.com


C# Throw Statement

Throw generates or translates exceptions. By using a throw statement inside a catch block, we can change the resulting exception. Alternatively we can throw a new exception. The throw statement is versatile and essential.


Example. We first look at three methods A, B, and C that use the throw statement in different ways. Method A uses a throw statement with no argument. This can be thought of as a rethrow—it throws the same exception already being handled.

Continuing on, method B throws a named exception variable. This is not a rethrow—it throws the same exception but changes the stack trace. We can collect information about the exception if needed. Method C creates a new exception.

Tip: You 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()
    {
	// 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");
	}
    }
}

Possible program output
    These three exceptions are thrown.

System.DivideByZeroException: Attempted to divide by zero.
System.DivideByZeroException: Attempted to divide by zero.
System.ArgumentNullException: Value cannot be null.
Parameter name: value


Rethrow. Next we look more carefully at the nature of rethrows in the C# language. A rethrow must use a throw statement with no argument. If you use throw ex, then the TargetSite and StackTrace are changed.

In this program, X() uses a rethrow statement. And Y() uses a throw ex statement. We see in the results that when a rethrow is used, the exception TargetSite is in StringToNumber—an internal method of int.Parse.

Parse

But: 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()


Summary. The exception handling mechanism reveals an alternative control pathway, one that separates error-specific logic from regular processing. And the throw statement provides the ability to rethrow an exception or generate a new one.

Thus: Throwing switches the program execution into an alternative exception handling pathway.

CatchDivideByZeroExceptionArgumentException: Invalid Arguments