Skip to content
This repository was archived by the owner on Jul 25, 2026. It is now read-only.

Repository files navigation

Important

This repository has moved. The code now lives in phmatray/dotnet-toolbelt under src/throwif — full git history preserved. This repository is archived (read-only). The NuGet package ID is unchanged.

CCross.ThrowIf banner

CCross.ThrowIf

phmatray - CCross.ThrowIf Top language Stars Forks

Issues Pull requests Last commit

Table of Contents

Throw your exceptions easily.

Please check the Website


Features

  • Value-returning guardsGuard.Against.* validates and returns the value in one expression (var id = Guard.Against.NegativeOrZero(userId);), so validation and assignment happen on the same line.
  • Rich validation surface – guards for null/empty/whitespace strings, numeric ranges, zero/negative values, GUIDs, emails, URLs, phone numbers, regex patterns, and date/time ranges.
  • Generic math support – numeric guards such as Negative, Zero, OutOfRange, and PowerOfTwo built on INumber<T> for C# 11 / .NET 7+ generic constraints.
  • Async & Task guardsGuard.Async helpers like CompletesWithin and NotFaulted for validating asynchronous operations and cancellation.
  • Span & collection guardsGuard.Span and collection guards (NotEmpty, NoNulls, Length, MinLength, AllNotNull) for zero-allocation, high-performance validation paths.
  • Fluent extension methodsGuardNullOrWhiteSpace(), GuardNullOrEmpty(), GuardNull() extension methods for inline chaining without static calls.
  • Multi-value & pattern guardsGuard.Multiple and Guard.Pattern for validating several values at once, exclusive-or checks, and Satisfies/Condition predicates.
  • Legacy expression-based API – the original ThrowIf.Argument / ThrowIf<TException> expression-based API is retained for backward compatibility.

Usage

Install from NuGet:

dotnet add package CCross.ThrowIf

Use Guard.Against to validate and use the value in a single expression:

using CCrossThrowIf;

public class OrderService
{
    private readonly IRepository _repository;

    public OrderService(IRepository repository, string connectionString)
    {
        // Validates and assigns in one line — throws if invalid
        _repository = Guard.Against.Null(repository);
        var validConnectionString = Guard.Against.NullOrEmpty(connectionString);
    }

    public async Task<Order?> PlaceOrderAsync(int quantity, CancellationToken cancellationToken)
    {
        // Guard.Against returns the validated value so it can be used directly
        var validQuantity = Guard.Against.NegativeOrZero(quantity);

        return await _repository.CreateOrderAsync(validQuantity, cancellationToken);
    }
}

Tech Stack

  • .NET 9
  • BenchmarkDotNet
  • xunit.v3
  • xunit.runner.visualstudio

Roadmap

  • Expand generic math guard coverage (additional range operators, more numeric predicates)
  • Add source-generator based guards for compile-time validation
  • Grow the benchmark suite with comparisons against other guard-clause libraries
  • Publish versioned API reference alongside the existing docs site
  • Add more collection and span guard overloads

See the open issues for details and to propose new guards.

Contributing

Contributions are welcome. Open an issue first to discuss any significant change.

  1. Fork the repository and create your branch (git checkout -b feat/my-feature)
  2. Commit your changes (git commit -m 'feat: ...')
  3. Push the branch and open a Pull Request

License

No license has been declared for this repository yet. Until one is added, default copyright applies — see choosealicense.com if you intend to open it up.

About

Fluent guard clauses for .NET — throw exceptions in one expressive line with auto-captured argument names

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

3 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages