An exception is thrown when an error is encountered in a running application, whether from bad code or bad user input. This post describes when and how to raise the ArgumentException and InvalidOperationException standard .NET exception types.
Exceptions can be thrown either by the runtime or the application code. This can be caused by bad code, while, other times, the problem is caused by bad user input that has not been accounted for in the application's code. When any of these errors occur, the system catches the error and raises an exception.
The process of generating and signaling the error is referred to as throwing an exception. This is done using the throw
keyword followed by a new instance of a class derived from System.Exception
. There are standard exception types provided by the .NET framework that you can use rather than creating a custom exception.
In this post, I'll show you why and how to use the ArgumentException
and InvalidOperationException
types which, are part of the standard exceptions in .NET.
Note: Interested in learning about the ArgumentNullException
and ArgumentOutOfRangeException
? Check out my post on those exceptions here.
The InvalidOperationException
exception type is thrown when a method call is invalid for the object's current state. This can be caused by changing a collection while iterating it, or casting a Nullable<T>
that is null to its underlying type. We can also throw this exception type in cases where we want to signal to our application that the requested operation through a method call can't be performed because the object is in an invalid state. Let's look at an example:
class Account
{
public Account(string firstName, string lastName, int balance)
{
FirstName = firstName;
LastName = lastName;
Balance = balance;
}
public string FirstName { get; private set; }
public string LastName { get; private set; }
public int Balance { get; private set; }
public void Withdraw(int amount)
{
if (amount > Balance)
throw new InvalidOperationException("Insufficient fund");
Balance = Balance - amount;
}
}
The code above shows an Account
class with properties to hold the account owner's names and account balance. The Withdraw
method deducts the withdrawal amount from the balance, and if the withdrawal amount is higher than the balance, it throws an exception — the InvalidOperationException
. When the exception is raised, it cancels the withdraw transaction and signals to the application that the account can't be debited of that amount because of insufficient funds.
The ArgumentException
type inherits from the System.SystemException
class and should be thrown when a method argument receives an invalid argument value. Carrying on from the Account
class example from the previous section, let's guard the Withdraw
method not to allow a number less than one, or an empty string as values for the names.
class Account
{
public Account(string firstName, string lastName, int balance)
{
if (string.IsNullOrEmpty(firstName))
throw new ArgumentException("FirstName is invalid");
if (string.IsNullOrEmpty(lastName))
throw new ArgumentException("LastName is invalid");
FirstName = firstName;
LastName = lastName;
Balance = balance;
}
public string FirstName { get; private set; }
public string LastName { get; private set; }
public int Balance { get; private set; }
public void Withdraw(int amount)
{
if (amount < 1)
throw new ArgumentException("Amount can't be less than 1",
nameof(amount));
if (amount > Balance)
throw new InvalidOperationException("Insufficient fund");
Balance = Balance - amount;
}
}
In the code above, we used the ArgumentException
exception in the constructor to prevent initializing an account object with invalid values. We also throw the ArgumentException
exception if the Withdraw
method is called with an amount less than one. We used the constructor that accepts an exception message and a second parameter to indicate the parameter that caused the exception.
We looked at throwing exceptions in C#, specifically, throwing the ArgumentException
and InvalidOperationException
that are part of the standard exceptions in .NET.
The ArgumentException
is thrown when a method argument receives an invalid argument value. The InvalidOperationException
exception is thrown in cases where the failure to invoke a method is caused by reasons other than invalid arguments. Because the InvalidOperationException
exception can be thrown in a wide variety of circumstances, it is important to read the exception message returned by the Message
property. How you handle the exception depends on the specific situation. Most commonly, however, the exception results from developer error and it can be anticipated and avoided.
Peter is a software consultant, technical trainer and OSS contributor/maintainer with excellent interpersonal and motivational abilities to develop collaborative relationships among high-functioning teams. He focuses on cloud-native architectures, serverless, continuous deployment/delivery, and developer experience. You can follow him on Twitter.