Writing new guards with extensions in C# 14

5/19/2025
2 minute read

In C# we have many nice guards sitting on top of static exceptions classes like ArgumentNullException, ArgumentOutOfRangeException, etc: As ArgumentException.ThrowIfNullOrEmpty, ArgumentException.ThrowIfNullOrWhiteSpace. Now we can extend them easily!

Extensions to the rescue

The new feature of C# 14 is that we can also extend type definitions with functions. This means we can add new guards to existing classes. If we want to have this "very useful": "Throw if our string has exactly one character" semantics, we can do something like this:

static class EnumExtensions
{
    extension(ArgumentException)
    {
        public static void ThrowIfHasOneCharacter(string argument, [CallerArgumentExpression("argument")] string? paramName = null)
        {
            if (argument.Length == 1)
            {
                throw new ArgumentException($"Argument '{paramName}' has exactly one character but shouldn't have.", paramName);
            }
        }
    }
}

Which then can be used like this:

public class MyClass
{
    public void MyMethod(string argument)
    {
        ArgumentException.ThrowIfHasOneCharacter(argument);
    }
}

That fits especially well with other already existing guards:

public class MyClass
{
    public void MyMethod(string argument)
    {
        ArgumentException.ThrowIfNullOrEmpty(argument);
        ArgumentException.ThrowIfHasOneCharacter(argument);
    }
}

Of course this is an overly simplified example. But you get the idea. We get something which makes it look and feel like the existing guards.

An error has occurred. This application may no longer respond until reloaded. Reload x