fernandostockler / GuardClauses

A collection of extension methods for validating method arguments in order to spot bugs as quickly as possible.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Guard Clauses

Designed to fail early when encountering arguments outside the correct specification.

The bugs I hate are the ones that show up only after hours of successful operation, under unusual circumstances, or whose stack traces lead to dead ends. -Martin Fowler.

Fail fast is a technique that exposes potential bugs early in development, making them immediately visible.

Assertions are the key to failing fast. An assertion is a tiny piece of code that checks a condition and then fails if the condition isn’t met. So, when something starts to go wrong, an assertion detects the problem and makes it visible. -Martin Fowler.

Usage

public enum Category { Client, Vip }

public class Person
{
    int id;
    string name;
    DateOnly birthday;
    Category category;
    double stars;

    public Person(int id, string name, DateOnly birthday, Category category, double stars)
    {
        this.id = Guard.Against.NegativeOrZero(id);

        this.name = Guard.Against.NullOrWhiteSpace(name)
            .And(x => x.Length <= 50, nameof(name))
            .And(x => x.Length >= 3, nameof(name));

        this.birthday = Guard.Against.OutOfRange(birthday,
            minimunValue: new DateOnly(1900, 1, 1),
            maximunValue: new DateOnly(2022, 1, 1));

        this.category = Guard.Against.EnumOutOfRange(category);

        this.stars = Guard.Against.OutOfRange(stars,
            minimunValue: 0,
            maximunValue: 5);
    }
}

Extensions methods

Method Exception
Guard.Against.Zero Throw a ArgumentException if the input number is zero.
Guard.Against.Negative Throw a ArgumentException if the input number is negative.
Guard.Against.NegativeOrZero Throw a ArgumentException if the input number is negative or zero.
Guard.Against.InvalidRegexFormat Throw a ArgumentException if the input number does not match with a Regex pattern.
Guard.Against.InvalidInput Throw a ArgumentException if the input does not pass a predicate function.
Guard.Against.OutOfRange Throw a ArgumentOutOfRangeException if the input is out of range.
Guard.Against.EnumOutOfRange Throw a InvalidEnumArgumentException if the input is a not defined enum.
Guard.Against.Null Throw a ArgumentNullException if the input is null.
Guard.Against.NullOrEmpty Throw a ArgumentNullException if the input is null or empty.
Guard.Against.NullOrWhiteSpace Throw a ArgumentNullException if the input is null, empty or white spaces.
And Throw a ArgumentException if the input does not satisfy a condition.

Custom extensions

You can create your own extension methods by simply extending the IGuardClause interface inside the GuardClauses.Extensions namespace.

namespace GuardClauses.Extensions;

public static class ZipCodeExtensions
{
    public static ZipCode InvalidZipCode(this IGuardClause guardClause, ZipCode zipCode)
        =>  ValidateZipCode(zipCode)
            ? zipCode
            : throw new ArgumentException($"ZipCode ({zipCode}) is invalid.", nameof(zipCode));
}

Usage:

public class Address
{
    string Line1, Line2, City, State, ZipCode;
    
    public Address(string line1, string line2, string city, string state, ZipCode zipCode)
    {
        Line1 = line1;
        ...
        ...
        ZipCode = Guard.Against.InvalidZipCode(zipCode);
    }
    
    ...
}

References

About

A collection of extension methods for validating method arguments in order to spot bugs as quickly as possible.

License:MIT License


Languages

Language:C# 100.0%