Author avatar

Peter Mbanugo

Commonly Encountered Exceptions – ArgumentOutOfRangeException

Peter Mbanugo

  • Nov 9, 2018
  • 8 Min read
  • 5,547 Views
  • Nov 9, 2018
  • 8 Min read
  • 5,547 Views
C#

Introduction

An exception is a runtime error in a program that violates a system or application constraint, or a condition that is not expected to occur during normal execution of the program. Possible causes of exceptions include attempting to connect to a database that no longer exists when a program tries to divide a number by zero, or opening a corrupted XML file. When these occur, the system catches the error and raises an exception. Catching exceptions is a way of handling these unexpected errors by defining a block of code that will be run when an exception is thrown.

There are a few commonly encountered exception types that are useful to be aware of. In this guide, we will look at the ArgumentOutOfRangeException exception type.

Encountering the ArgumentOutOfRangeException Exception Type

The ArgumentOutOfRangeException exception is thrown when the argument passed to a method is not null and contains a value that is not within the set of expected values. This exception type has the properties ParamName and ActualValue which helps understand the cause of the exception. The ParamName property identifies the parameter name of the invalid argument and the ActualValue property identifies the invalid value if a value is present.

The ArgumentOutOfRangeException exception would normally result from developer error and if the value of the argument is returned by a method call or input from the user before being passed to the method that throws the exception, you should validate arguments before passing them to the method. The ArgumentOutOfRangeException is used extensively by classes in the System.Collections namespace. A typical scenario is when your code wants to remove an item at a certain index from a collection and the collection is either empty or the index you specified through the argument is negative or higher than the size of the collection. The following example demonstrates this:

1using System;
2using System.Collections.Generic;
3
4class Program
5{
6  static void Main(string[] args)
7  {
8    try
9    {
10      var numbers = new List<int>();
11      var index = 0;
12      Console.WriteLine("Removing item at index {0}", index);
13
14      numbers.RemoveAt(index);
15    }
16    catch (ArgumentOutOfRangeException ex)
17    {
18      Console.WriteLine("Oh no! Something went wrong");
19      Console.WriteLine(ex);
20    }
21  }
22}
csharp

The example above displays the following output when you run it:

1Removing item at index 0
2Oh no! Something went wrong
3System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
4Parameter name: index
5   at System.Collections.Generic.List`1.RemoveAt(Int32 index)
6   at MyApp.Program.Main(String[] args) in /dotnet/MyApp/Program.cs:line 13

To prevent the exception, we can check whether the collection's Count property is greater than zero and the index to remove it is also less than the value in Count, before attempting to remove any member in the collection. We will update the code statement inside the try block to read as follows:

1var numbers = new List<int>() { 1, 2 };
2var index = 2;
3Console.WriteLine("Attempting to remove item at index {0}", index);
4
5if (numbers.Count > 0 && index < numbers.Count)
6{
7  numbers.RemoveAt(index);
8  Console.WriteLine("Removed item at index {0}", index);
9}
csharp

That will help us avoid running into an exception. For more scenarios that leads to ArgumentOutOfRangeException exception, read the docs.

Throwing the ArgumentOutOfRangeException Exception Type

While the ArgumentOutOfRangeException is extensively used by classes in the System.Collections and System.IO namespaces, the Array class, and string manipulation methods in the String class, we can also use it to throw exceptions in our code to signal that the value of an argument is outside of the expected range. Let's look at an example of how we can use it. Create a new Console application project and update Program.cs with the code below.

1namespace MyApp
2{
3    using System;
4
5    class Program
6    {
7        static void Main(string[] args)
8        {
9            try
10            {
11                Console.WriteLine("Enter account name");
12                var name = Console.ReadLine();
13
14                Console.WriteLine("Enter opening balance");
15                var balance = Convert.ToInt32(Console.ReadLine());
16
17                Console.WriteLine("Opening account for {0}... \n", name);
18                var account = new Account(name, balance);
19                Console.WriteLine("Account opened for {0}", account.Name);
20            }
21            catch (ArgumentOutOfRangeException ex)
22            {
23                Console.WriteLine("Oh no! Something went wrong");
24                Console.WriteLine(ex);
25            }
26        }
27
28        class Account
29        {
30            public Account(string name, int balance)
31            {
32                if (balance < 1200)
33                    throw new ArgumentOutOfRangeException(nameof(balance), balance, "The account balance can't be less than 1200");
34                Name = name;
35                Balance = balance;
36            }
37            public string Name { get; private set; }
38            public int Balance { get; private set; }
39        }
40    }
41}
csharp

In the code above, we have an Account class with properties Name and Balance, and a constructor that accepts name and balance as parameters. When this constructor with balance less than 1200, it'll throw an ArgumentOutOfRangeException exception with the parameter name that caused the exception, the value of the argument, and message explaining the cause of the error. In the static Main method we collect the name and balance from the user, then create an Account object with those information.

If we run the application and enter a value less than 1200 for the balance, we will get an exception. The information below is what we get when we run the code with 900 as the balance.

1Enter account name
2Philly
3Enter opening balance
4900
5Opening account for Philly...
6
7Oh no! Something went wrong
8System.ArgumentOutOfRangeException: The account balance can't be less than 1200
9Parameter name: balance
10Actual value was 900.
11   at MyApp.Program.Account..ctor(String name, Int32 balance) in /dotnet/MyApp/Program.cs:line 34
12   at MyApp.Program.Main(String[] args) in /dotnet/MyApp/Program.cs:line 18

That's a Wrap

The ArgumentOutOfRangeException exception is thrown when the value of an argument is outside the expected range of values as defined by the invoked method. The ArgumentOutOfRangeException exception normally results from developer error so when dealing with this kind of error, be sure to read the value of the properties Message, ParamName, and ActualValue. If the value of the argument is returned from a method call or input from the user before being passed to the method that throws the exception, you should validate the arguments before passing them to the method.

We looked at a scenario where calling RemoveAt method of a collection could cause this exception alongside how to resolve the error. I also showed an example that demonstrates when it'll be useful to throw the ArgumentOutOfRangeException from your methods. This should leave you equipped to handle and utilise this exception type!