SkillAgentSearch skills...

GuardAgainst

Useful guard clauses that simplify argument validity checking and make your code more readable.

Install / Use

/learn @pm7y/GuardAgainst
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

<img src="/src/GuardAgainstLib/logo/GuardAgainstSquare.png" width="64">

GuardAgainst CI

Useful guard clauses that simplify argument validity checking and make your code more readable.

<br/>

Installation

Via Source

Just copy the source file into your project and change the namespace to match your own.

Via NuGet

Install-Package GuardAgainst
<br/>

Why would I use it?

Code becomes more readable and concise. Consider the following example: a simple GetFullname method that concatenates a firstname and surname string together.

private static string GetFullname(string firstname, string surname)
{
    if (firstname is null)
    {
        throw new ArgumentNullException(nameof(firstname), "Firstname is required.");
    }

    if (string.IsNullOrWhiteSpace(firstname))
    {
        throw new ArgumentException("Firstname is required.", nameof(firstname));
    }

    if (surname is null)
    {
        throw new ArgumentNullException(nameof(surname));
    }

    if (string.IsNullOrWhiteSpace(surname))
    {
        throw new ArgumentException("Surname is required.", nameof(surname));
    }

    return $"{firstname} {surname}";
}

It checks that firstname and surname arguments are not null or whitespace and throws an ArgumentNullException or ArgumentException respectively. The nameof the offending argument is passed to the exception constructor so that when the exception is thrown we'll know the name of argument that was at fault.

This kind of boiler plate code is tedious to write, can be error prone in itself, and can add unneccessary cognitive load when scanning the source. GuardAgainst aims to abstract this boiler plate code into a series of static helper methods that you can use to achieve the same result.

Hopefully you'll agree that this is much simpler and easier to read...

private static string GetFullname(string firstname, string surname)
{
    GuardAgainst.ArgumentBeingNullOrWhitespace(firstname, msg: "Firstname is required.");
    GuardAgainst.ArgumentBeingNullOrWhitespace(surname, msg: "Surname is required.");

    return $"{firstname} {surname}";
}

Both implementations of GetFullname are achieving the exact same thing.

GuardAgainst.ArgumentBeingNullOrWhitespace accepts 2 main arguments: -

  • argumentValue is required. This is the value that you want to validate.
  • argumentName is optional. It will be added be the compiler automatically via the CallerArgumentExpression.
  • exceptionMessage is optional. Allows you to give a specific error message to pass to the exception constructor.
<br/>

There are several other helper methods available that act in a similar fashion. See table below for the full list.

Available Methods

| Guard against being null, whitespace or empty | Description | | :--------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | GuardAgainst.ArgumentBeingNull | - Throws an ArgumentNullException when the value is null. | | GuardAgainst.ArgumentBeingNullOrWhitespace | - Throws an ArgumentNullException when the value is null. <br/>- Throws an ArgumentException when the value is a whitespace only string. | | GuardAgainst.ArgumentBeingWhitespace | - Throws an ArgumentException when the value is a whitespace only string. | | GuardAgainst.ArgumentBeingNullOrEmpty | - Throws an ArgumentNullException when the value is null. <br/>- Throws an ArgumentException when the value is an empty string. | | GuardAgainst.ArgumentBeingEmpty | - Throws an ArgumentException when the value is an empty string or Enumerable. | | Guard against being out of range | Description | | GuardAgainst.ArgumentBeingNullOrLessThanMinimum | - Throws an ArgumentNullException when the value is null. <br/>- Throws an ArgumentOutOfRangeException when the value is less than the minimum allowed value. | | GuardAgainst.ArgumentBeingLessThanMinimum | - Throws an ArgumentOutOfRangeException when the value is less than the minimum allowed value. | | GuardAgainst.ArgumentBeingNullOrGreaterThanMaximum | - Throws an ArgumentNullException when the value is null. <br/>- Throws an ArgumentOutOfRangeException when the value is greater than the maximum allowed value. | | GuardAgainst.ArgumentBeingGreaterThanMaximum | - Throws an ArgumentOutOfRangeException when the value is greater than the maximum allowed value. | | GuardAgainst.ArgumentBeingNullOrOutOfRange | - Throws an ArgumentNullException when the value is null. <br/>- Throws an ArgumentOutOfRangeException when the value is less than the minimum allowed value. <br/>- Throws an ArgumentOutOfRangeException when the value is greater than the maximum allowed value. | | GuardAgainst.ArgumentBeingOutOfRange | - Throws an ArgumentOutOfRangeException when the value is less than the minimum allowed value. <br/>- Throws an ArgumentOutOfRangeException when the value is greater than the maximum allowed value. | | Other | Description | | GuardAgainst.ArgumentBeingInvalidEnum | - Throws an ArgumentException of enum is the specified invalid value. | | GuardAgainst.OperationBeingInvalid | - Throws an InvalidOperationException if the condition is not satisfied. | |

<br/>

Why wouldn't I use it?

There are actually a few reasons you might not want to use a guard clause library. Travis Illig has a nice blog post detailing a few of them.

https://www.paraesthesia.com/archive/2011/09/30/six-reasons-not-to-use-guard-classes.aspx/

Here's the tl;dr; of his article with some of my counter arguments.

  • "Guard classes defeat static analysis like FxCop."
    • You shouldn't have to change your code to work around short comings in your static analysis tools. Your tools should work for you, not the other way around. Is FxCop still even a thing?
  • "Guard classes become giant validation dumping grounds."
    • I like to think GuardAgainst supports a useful and flexible set of scenarios.
  • "Guard classes mess up the call stack."
    • True, there's no getting around it. GuardAgainst will add one extra line. But when you look at the call stack of the error message this should be completely obvious and you should see exactly which parameter caused the exception and why.
  • "Guard classes become a single point of failure."
    • **That could be said of many libraries out there though (e.g. the npm padleft debacle). Pick a good library (like GuardAgainst 😉) and report bugs or raise a PR to fix issues

Related Skills

View on GitHub
GitHub Stars13
CategoryDevelopment
Updated1y ago
Forks1

Languages

C#

Security Score

80/100

Audited on Nov 24, 2024

No findings