How to create custom exceptions - C#

C# includes a wide range of exception types, such as NullReferenceException, DivideByZeroException, ArgumentException, and many more.

However, you'll likely want to raise a specific exception when an application rule is broken.

To do this, you'll need to create a custom exception.

Creating a custom exception

Let's take a look at the following example:

public static void Main (string[] args) 
{
    PrintName("Sean");
}

static void PrintName(string name)
{
    if(name == null)
    {
        throw new NullReferenceException("Name is null");
    }

    Console.WriteLine($"Hello {name}!");
}

If we pass any string parameter into PrintName, it will write it to the console.

If we pass null, then it will throw a NullReferenceException.

But what if we gave it an invalid name format? For instance:

PrintName("Sean123");

We could detect for numerical values, and throw an ArgumentException.

Alternatively, we could create our own exception, and throw that instead:

class InvalidNameException : Exception
{
    public InvalidNameException() { }

    public InvalidNameException(string name, string reason)
        : base($"This name is not valid: {name}. {reason}")
    {

    }
}

To provide the class with the functionality of an exception, we've inherited from Exception.

You may want to inherit from a different exception base class, for instance ArgumentException would be reasonable in this scenario.

Throwing a custom exception

Fortunately, throwing a custom exception is no different to throwing a built-in exception.

Let's check for numerical characters passed into PrintName, and throw an exception if we find any:

using System;
using System.Linq;

class CustomExceptions 
{
    public static void Main (string[] args) 
    {
        PrintName("Sean123");
    }

    static void PrintName(string name)
    {
        if(name == null)
        {
            throw new NullReferenceException("Name is null");
        }

        if(name.Any(char.IsDigit))        {            throw new InvalidNameException(name, "Names should not contain numbers.");        }        Console.WriteLine($"Hello {name}!");
    }
}

class InvalidNameException : Exception{    public InvalidNameException() { }    public InvalidNameException(string name, string reason)        : base($"This name is not valid: {name}. {reason}")    {    }}

When we execute, we're presented with our unhandled, but custom-made exception:

Unhandled Exception:
InvalidNameException: This name is not valid: Sean123. Names should not contain numbers.
  at CustomExceptions.PrintName (System.String name) [0x00044] in <4d9750a1cd8b47e7a24e65dd5f4e63f1>:0 
  at CustomExceptions.Main (System.String[] args) [0x00000] in <4d9750a1cd8b47e7a24e65dd5f4e63f1>:0