TheDeveloperBlog.com


C# ArgumentException: Invalid Arguments

ArgumentException. A method can be called with invalid arguments. An ArgumentException may be thrown in this case. Exceptions use derived types to indicate their meaning. But this does not give them extra abilities.

Note: Semantically, ArgumentException indicates that a method was called with an invalid argument.


Example. This method receives one formal parameter, a string type with the identifier "argument". In the method A, we perform two checks on the value of the variable argument, detecting when it is null or has zero characters in its buffer.

NullEmpty Strings

Constructor. When using the ArgumentNullException constructor, you can pass a string literal that is equal to the variable name that was null. This affects the debug output and will aid debugging.

Tip: You can use the same pattern on ArgumentException, which indicates a general argument-related exception.

Based on:

.NET 4.5

C# program that uses ArgumentException

using System;

class Program
{
    static void Main()
    {
	// Demonstrate the argument null exception.
	try
	{
	    A(null);
	}
	catch (Exception ex)
	{
	    Console.WriteLine(ex);
	}
	// Demonstrate the general argument exception.
	try
	{
	    A("");
	}
	catch (Exception ex)
	{
	    Console.WriteLine(ex);
	}
	// Flow path without exception.
	Console.WriteLine(A("test"));
    }

    static int A(string argument)
    {
	// Handle null argument.
	if (argument == null)
	{
	    throw new ArgumentNullException("argument");
	}
	// Handle invalid argument.
	if (argument.Length == 0)
	{
	    throw new ArgumentException("Zero-length string invalid", "argument");
	}
	return argument.Length;
    }
}

Output: truncated

System.ArgumentNullException: Value cannot be null.
Parameter name: argument
    at Program.A(String argument)...
System.ArgumentException: Zero-length string invalid
Parameter name: argument
    at Program.A(String argument)...
4

An interesting part of this example. The parameter name, which is specified as the string literal in both exception constructors, is written to the output. The argument name is important as a debugging aid.

Example: Maybe the method A would receive two strings, and neither of them could be validly null—the argument name would be helpful.


Discussion. There are some cases where you should validate arguments with more care. If you have a method that is called in many different places or any external places written by external developers, then validating arguments is more important.

But: With an internal method, the arguments may not need to be carefully validated because they may never be invalid.

So: For truly performance-critical methods, do not validate arguments in most cases.


ArgumentNullException is thrown by code that checks arguments for null and then throws it explicitly. Usually, the method would fail with a NullReferenceException if the check was removed. Here, we use null on the Dictionary indexer.

DictionaryIndexer

And: The indexer compiles to the get_Item method. Internally, get_Item eventually uses the statement "throw new ArgumentNullException".

C# program that causes ArgumentNullException

using System.Collections.Generic;

class Program
{
    static void Main()
    {
	var dictionary = new Dictionary<string, int>();
	int value = dictionary[null];
    }
}

Output

Unhandled Exception: System.ArgumentNullException: Value cannot be null.
Parameter name: key


User code. The ArgumentNullException can be understood as an exception that is thrown by user code, not the runtime. It thus represents an error that was carefully added to help the users of the library better understand what is wrong.

Tip: In many cases, avoiding the null check and allowing the runtime itself to detect a NullReferenceException would be faster.


ArgumentOutOfRangeException. This program causes an ArgumentOutOfRangeException to be thrown by the Substring method. The Substring method requires its argument to be greater than or equal to zero. In this program, this requirement is not met.

Substring

Tip: Internally, Substring checks its argument for a negative value. With this exception, it alerts you to an invalid value.

And: This error is helpful. It makes your program easier to fix. It pinpoints the nature of your logical error.

C# program that causes ArgumentOutOfRangeException

class Program
{
    static void Main()
    {
	string value = "test".Substring(-1);
    }
}

Output

Unhandled Exception:
System.ArgumentOutOfRangeException: StartIndex cannot be less than zero.
Parameter name: startIndex

In this example, the ArgumentOutOfRangeException is thrown explicitly, with a throw statement, not by the runtime. This makes it useful because it indicates a specific cause of what happened. The message helps you pinpoint the cause.

Throw

Summary. We looked at the ArgumentException and ArgumentNullException types. In the exception type hierarchy, the type names are a way to encode the meaning of the exception's cause. These exceptions indicate an argument problem.

Review: The ArgumentException and ArgumentNullException types are semantically rich and aid in efficient debugging.