A high-performance .NET library for defensive argument validation and exception handling. Provides two complementary APIs: Check for performance-critical validation and Throw for detailed exception reporting.
dotnet add package CheckAndThrowCheckAndThrow implements a philosophy that separates concerns when validating inputs and handling errors:
Check.*methods prioritize performance. They validate conditions as efficiently as possible with minimal overhead, making them suitable for hot paths and performance-sensitive code.Throw.*methods prioritize detailed diagnostics. They sacrifice speed for comprehensive error information, generating rich exception messages that help developers diagnose issues quickly.
This design reflects the principle that exceptions should be exceptional. Since exceptions are not expected to be thrown frequently in production code, the extra overhead of detailed error reporting is justified, your code's hot paths stay fast through Check, while debugging becomes effortless through Throw.
Fast argument validation with minimal overhead:
Check.Arg.*— Validate single arguments (null checks, type checks, range validation, collection checks)Check.Args.*— Validate multiple arguments togetherCheck.State.*— Validate application state conditionsCheck.Expression.*— Evaluate expressions for state validation
Perfect for:
- Entry points of hot methods
- Loops and frequently-called code
- Performance-critical paths
Detailed exception reporting for when things go wrong:
Throw.Arg.*— Throw rich ArgumentExceptions with contextThrow.State.*— Throw InvalidOperationExceptions with diagnostic infoThrow.Unreachable(),Throw.NotImplemented(),Throw.NotSupported()— Handle unreachable code paths
Perfect for:
- Helper methods and validation logic
- Clear separation of error reporting from validation
- Comprehensive debugging information in exceptions
Key insight: Check methods call Throw methods underneath when validation fails.
This means:
- Success path → Fast:
Checkvalidates with minimal overhead - Failure path → Detailed:
Checkdelegates toThrowfor rich error reporting
// Check validates efficiently; delegates to Throw on failure
public void ProcessData(int[] data)
{
Check.Arg.NotNull(data); // Returns immediately if valid
// Calls Throw.Arg.IsNull internally if null
// ... process data ...
}
// You can also use Throw directly for explicit error handling
public User GetUser(UserType userType)
{
return userType switch
{
UserType.Admin => GetAdmin(),
UserType.Customer => GetCustomer(),
// Generic return type allows usage in switch expressions
_ => Throw.Arg.IsNotDefined<User>(typeof(UserType), userType)
};
}Why this design? Since exceptions interrupt execution and are handled at a higher level anyway, the performance cost of detailed error messages is negligible. This architecture ensures:
- Your application remains responsive in the common case (success)
- Rich debugging information available in the exceptional case (failure)
- Clean, readable validation code everywhere
Add CheckAndThrow to your project via NuGet:
dotnet add package CheckAndThrow- DotNet standard 2.0
- DotNet standard 2.1
- DotNet 8.0
- DotNet 10.0
Contributions are welcome! Please:
- Open an issue to discuss your idea
- Submit pull requests with clear descriptions and appropriate tests
- Ensure all public members have XML documentation comments
Licensed under the MIT License. See LICENSE file for details.