Baike.dev
All toolsOnline toolsAI codingTrendingOpen sourceNewsSubmit
Log in
< Back to tools
T

throw

> 编程语言
Open source

A simple, fluent, extensible, and fully customizable library for throwing exceptions for projects using .NET 6+

1.3K stars0 likes1 views
WebsiteGitHub

About

A simple, fluent, extensible, and fully customizable library for throwing exceptions for projects using .NET 6+

  • Give it a star ⭐!
  • Nullable vs non-nullable types
  • Customize everything
    • How customizing the exception affects the chained rules
    • Exception customizations
      • 1. Throw()
      • 2. Throw("My custom message")
      • 3. Throw(() => new MyException())
      • 4. Throw(paramName => new MyException($"Param: {paramName}")
  • Usage
    • Common types
      • Booleans
      • Nullable value types (bool?, int?, double?, DateTime? etc.)
      • Strings
      • Collections (IEnumerable, IEnumerable, ICollection, ICollection, IList, etc.)
      • DateTime
      • Enums
      • Equalities (non-nullables)
      • Uris
      • Comparable (int, double, decimal, long, float, short, DateTime, DateOnly, TimeOnly etc.)
      • Types
    • Nested properties
      • Boolean properties
      • String properties
      • Collection properties
      • DateTime properties
      • Enum properties
      • property equalities
      • Uri properties
      • Comparable properties
  • Extensibility
  • Conditional compilation
  • Upcoming features
  • Contribution
  • Credits
  • License

Give it a star ⭐!

Loving it? Show your support by giving this project a star!

Nullable vs non-nullable types

This library is designed to work best with nullable reference types feature enabled.

The Throw() method is the entry method for all non-nullable types:

csharp
string name = "hello";
name.Throw().IfLongerThan(10);

And ThrowIfNull() for any nullable type:

csharp
string? name = "hello";
name.ThrowIfNull();

Trying to use Throw() on a nullable type will give a warning

csharp
string? name = null;
name.Throw() // warning CS8714: The type 'string?' cannot be used as type parameter 'TValue' in the generic type or method 'ValidatableCreationExtensions.Throw(TValue, ExceptionCustomizations?, string?)'. Nullability of type argument 'string?' doesn't match 'notnull' constraint.
    .IfEmpty();

After validating that the nullable type isn't null, all the regular non-nullable rules can be used

csharp
name.ThrowIfNull()
    .IfEmpty()
    .IfLongerThan(3);

The expression can be implicitly cast to the non-nullable type of the original nullable type

csharp
string? name = "Amichai";
string nonNullableName = name.ThrowIfNull()
    .IfEmpty()
    .IfLongerThan(10);

or

csharp
int? a = 5;
int b = a.ThrowIfNull();

Customize everything

How customizing the exception affects the chained rules

If you have customized the exception, any rule that throws an exception will use the customization. For example:

…

At any point, you can change the exception customization, and it will apply for all the rules that follow. For example:

…

To go back to the default exception, simply use the Throw() method. For example:

csharp
name.Throw("String should not be empty or white space only.")
        .IfEmpty() // System.ArgumentException: String should not be empty or white space only. (Parameter 'name')
        .IfWhiteSpace() // System.ArgumentException: String should not be empty or white space only. (Parameter 'name')
    .Throw()
        .IfLongerThan(3) // System.ArgumentException: String should not be longer than 3 characters. (Parameter 'name')
        .IfShorterThan(10); // System.ArgumentException: String should not be shorter than 10 characters. (Parameter 'name')

Exception customizations

1. Throw()

Each rule has a default behavior. If you don't customize the exception, the default behavior will be used.

Use the Throw() or ThrowIfNull() method to throw the default exception

…

2. Throw("My custom message")

Pass a custom exception message to the Throw() or ThrowIfNull() method

…

3. Throw(() => new MyException())

Pass a custom exception thrower to the Throw() or ThrowIfNull() method

…

4. Throw(paramName => new MyException($"Param: {paramName}")

Pass a custom exception thrower to the Throw() or ThrowIfNull() method, that takes the parameter name as a parameter

This comes in handy in scenarios like this:

…
…

Usage

Common types

Booleans

csharp
value.Throw().IfTrue(); // ArgumentException: Value should not be true (Parameter 'value')
value.Throw().IfFalse(); // ArgumentException: Value should be true (Parameter 'value')

// Any method which returns bool can inline it's exception throwing logic.
Enum.TryParse("Unexpected value", out EmployeeType value)
    .Throw()
    .IfFalse(); // System.ArgumentException: Value should be true. (Parameter 'Enum.TryParse("Unexpected value", out EmployeeType value)')

Nullable value types (bool?, int?, double?, DateTime? etc.)

csharp
bool? value = null;

value.ThrowIfNull(); // ArgumentNullException: Value cannot be null. (Parameter 'value')

// After validating `ThrowIfNull`, any of the regular value type extensions can be used.
value.ThrowIfNull() // ArgumentNullException: Value cannot be null. (Parameter 'value')
    .IfTrue(); // ArgumentException: Value should not be true (Parameter 'value')

// The returned value from `ThrowIfNull` can be implicitly cast to the original non-nullable type.
bool nonNullableValue = value.ThrowIfNull(); // ArgumentNullException: Value cannot be null. (Parameter 'value')

Strings

…

Collections (IEnumerable, IEnumerable, ICollection, ICollection, IList, etc.)

Important note: if the collection is a non-evaluated expression, the expression will be evaluated.

…

DateTime

…

Enums

csharp
employeeType.Throw().IfOutOfRange(); // System.ArgumentOutOfRangeException: Value should be defined in enum. (Parameter 'employeeType')
employeeType.Throw().IfEquals(EmployeeType.FullTime); // System.ArgumentException: Value should not be equal to FullTime. (Parameter 'employeeType')

Equalities (non-nullables)

csharp
dateTime.Throw().IfDefault(); // System.ArgumentException: Value should not be default. (Parameter 'dateTime')
dateTime.Throw().IfNotDefault(); // System.ArgumentException: Value should be default. (Parameter 'dateTime')
number.Throw().IfEquals(5); // System.ArgumentException: Value should not be not be equal to 5. (Parameter 'number')
number.Throw().IfNotEquals(3); // System.ArgumentException: Value should be equal to 3. (Parameter 'number')

Uris

…

Comparable (int, double, decimal, long, float, short, DateTime, DateOnly, TimeOnly etc.)

…

Types

csharp
myObject.Throw().IfType(); // System.ArgumentException: Parameter should not be of type 'String'. (Parameter 'myObject').
myObject.Throw().IfNotType(); // System.ArgumentException: Parameter should be of type 'String'. (Parameter 'myObject').

Nested properties

Boolean properties

…

Collection properties

…

DateTime properties

…

Enum properties

csharp
person.Throw().IfOutOfRange(p => p.EmployeeType); // System.ArgumentOutOfRangeException: Value should be defined in enum. (Parameter 'person: p => p.EmployeeType')
person.Throw().IfEquals(p => p.EmployeeType, EmployeeType.FullTime); // System.ArgumentException: Value should not be equal to FullTime. (Parameter 'person: p => p.EmployeeType')

property equalities

…

Uri properties

…

Comparable properties

…

Extensibility

You can easily extend the library by adding your own rules.

Here is a simple example:

csharp
"foo".Throw().IfFoo(); // System.ArgumentException: String shouldn't equal 'foo' (Parameter '"foo"')
csharp
namespace Throw
{
    public static class ValidatableExtensions
    {
        public static ref readonly Validatable IfFoo(this in Validatable validatable)
        {
            if (string.Equals(validatable.Value, "foo", StringComparison.OrdinalIgnoreCase))
            {
                throw new ArgumentException("String shouldn't equal 'foo'", validatable.ParamName);
            }

            return ref validatable;
        }
    }
}

Another example:

csharp
user.Throw().IfUsesFacebookOnChrome();
csharp
namespace Throw
{
    public static class ValidatableExtensions
    {
        public static ref readonly Validatable IfUsesFacebookOnChrome(this in Validatable validatable)
        {
            if (validatable.Value.FavoriteBrowser == Browser.Chrome && validatable.Value.FavoriteWebsite == new Uri("https://facebook.com"))
            {
                throw new UserException("User shouldn't use Facebook on Chrome!");
            }

            return ref validatable;
        }
    }
}

If you want to use the exception customizations in your extension. You can use the ExceptionThrower class which knows how to create the appropriate exception based on the customizations. For example:

csharp
namespace Throw
{
    public static class ValidatableExtensions
    {
        public static ref readonly Validatable IfUsesFacebookOnChrome(this in Validatable validatable)
        {
            if (validatable.Value.FavoriteBrowser == Browser.Chrome && validatable.Value.FavoriteWebsite == new Uri("https://facebook.com"))
            {
                ExceptionThrower.Throw(validatable.ParamName, validatable.ExceptionCustomizations, "User shouldn't be using Facebook on Chrome.");
            }

            return ref validatable;
        }
    }
}

This will behave as following:

csharp
user.Throw()
    .IfUsesFacebookOnChrome(); // System.ArgumentException: User shouldn't be using Facebook on Chrome. (Parameter 'user')
csharp
user.Throw("A different message.")
    .IfUsesFacebookOnChrome(); // System.ArgumentException: A different message. (Parameter 'user')
csharp
user.Throw(() => new Exception("A different exception."))
    .IfUsesFacebookOnChrome(); // System.Exception: A different exception.
csharp
user.Throw(paramName => new Exception($"A different exception. Param name: '{paramName}'"))
    .IfUsesFacebookOnChrome(); // System.Exception: A different exception. Param name: 'user'

Conditional compilation

Have a Throw() rule that you want to exclude from your release build? Simply add OnlyInDebug() to the rule and it will be excluded from non-debug builds.

csharp
"foo".Throw().IfEquals("foo").OnlyInDebug();
bash
dotnet run -c Debug # will throw
bash
dotnet run -c Release # won't throw

Upcoming features

  • More extension methods: Many more rules to come! Please contribute!

Contribution

Feel free to open an issue with any idea, bug, or feature request.

We are trying to be the fastest validation library, so if you have suggestions on improving the runtime speed, share them with us.

Credits

  • Dawn.Guard - An awesome, fast, and intuitive guard clause library for C#. Was a great inspiration for this library.

License

This project is licensed under the terms of the [MIT](https://gith

Issues· 0 open

View all issuesOpen on GitHub

No open issues yet, or sync has not completed.

> Tags

C#argumentassertassertionclause

No comments yet. Be the first to share.

> Details

PublishedAug 1, 2026
UpdatedSep 17, 2026
Category编程语言
PricingOpen source

> Related tools

T
TypeScript
JavaScript 的超集,为前端与全栈提供静态类型
P
Python
通用编程语言,广泛用于 Web、数据与 AI
G
Go
Google 推出的简洁高效系统语言