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