Pluralsight Logo
Author avatar

Peter Mbanugo

Author badge Author

Commonly Encountered Exceptions – ArgumentOutOfRangeException

Peter Mbanugo

Author BadgeAuthor
  • Nov 9, 2018
  • 8 Min read
  • 16 Views
  • Nov 9, 2018
  • 8 Min read
  • 16 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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
using System;
using System.Collections.Generic;

class Program
{
  static void Main(string[] args)
  {
    try
    {
      var numbers = new List<int>();
      var index = 0;
      Console.WriteLine("Removing item at index {0}", index);

      numbers.RemoveAt(index);
    }
    catch (ArgumentOutOfRangeException ex)
    {
      Console.WriteLine("Oh no! Something went wrong");
      Console.WriteLine(ex);
    }
  }
}
csharp

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

1
2
3
4
5
6
Removing item at index 0
Oh no! Something went wrong
System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
   at System.Collections.Generic.List`1.RemoveAt(Int32 index)
   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:

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

if (numbers.Count > 0 && index < numbers.Count)
{
  numbers.RemoveAt(index);
  Console.WriteLine("Removed item at index {0}", index);
}
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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
namespace MyApp
{
    using System;

    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                Console.WriteLine("Enter account name");
                var name = Console.ReadLine();

                Console.WriteLine("Enter opening balance");
                var balance = Convert.ToInt32(Console.ReadLine());

                Console.WriteLine("Opening account for {0}... \n", name);
                var account = new Account(name, balance);
                Console.WriteLine("Account opened for {0}", account.Name);
            }
            catch (ArgumentOutOfRangeException ex)
            {
                Console.WriteLine("Oh no! Something went wrong");
                Console.WriteLine(ex);
            }
        }

        class Account
        {
            public Account(string name, int balance)
            {
                if (balance < 1200)
                    throw new ArgumentOutOfRangeException(nameof(balance), balance, "The account balance can't be less than 1200");
                Name = name;
                Balance = balance;
            }
            public string Name { get; private set; }
            public int Balance { get; private set; }
        }
    }
}
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.

1
2
3
4
5
6
7
8
9
10
11
12
Enter account name
Philly
Enter opening balance
900
Opening account for Philly...

Oh no! Something went wrong
System.ArgumentOutOfRangeException: The account balance can't be less than 1200
Parameter name: balance
Actual value was 900.
   at MyApp.Program.Account..ctor(String name, Int32 balance) in /dotnet/MyApp/Program.cs:line 34
   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!

1