Lightweight, high-performance library providing guard clauses for validating method parameters and ensuring defensive programming practices in .NET applications.
Built specifically for defensive programming with performance and developer experience in mind.
Minimal overhead with inline methods and zero allocations for successful validations. Built for production workloads.
Full support for generics and nullable reference types with compile-time safety and IntelliSense support.
Uses CallerArgumentExpression for automatic parameter name capture and supports the latest .NET versions.
Install Guardian and start writing defensive code immediately.
Or via Package Manager Console:
using Guardian;
public class Product
{
public string Name { get; }
public decimal Price { get; }
public int StockQuantity { get; }
public Product(string name, decimal price, int stockQuantity)
{
Name = Guard.Against.NullOrWhiteSpace(name);
Price = Guard.Against.NegativeOrZero(price);
StockQuantity = Guard.Against.Negative(stockQuantity);
}
}
Comprehensive validation methods for all common scenarios and edge cases.
Throws if value is null
Throws if string/collection is null or empty
Throws if string is null, empty, or whitespace
Throws if value equals default(T)
Throws if value is negative
Throws if value is zero
Throws if value is negative or zero
Throws if value is outside specified range
Throws if value exceeds maximum
Throws if value is below minimum
Throws if string doesn't match regex pattern
Throws if string length is outside range
Throws if collection is null or empty
Throws if value is not a defined enum value
Throws if custom condition is false
Throws if value is not in allowed list
See Guardian in action with practical examples from common development scenarios.
Validate constructor parameters to ensure objects are created in a valid state from the start.
public class Customer
{
public Guid Id { get; }
public string Name { get; }
public int Age { get; }
public string Email { get; }
public Customer(Guid id, string name, int age, string email)
{
Id = Guard.Against.Default(id);
Name = Guard.Against.InvalidLength(name, 2, 100);
Age = Guard.Against.OutOfRange(age, 18, 120);
Email = Guard.Against.InvalidFormat(email,
@"^[^@\s]+@[^@\s]+\.[^@\s]+$");
}
}
Validate method parameters at the entry point to prevent invalid operations and provide clear error messages.
public void ProcessOrder(Guid orderId, string customerEmail,
decimal amount, List<Item> items)
{
// Basic validation
Guard.Against.Default(orderId);
Guard.Against.InvalidFormat(customerEmail,
@"^[^@\s]+@[^@\s]+\.[^@\s]+$");
Guard.Against.OutOfRange(amount, 0.01m, 10000m);
Guard.Against.NullOrEmpty(items);
// Business rule validation
var totalItemValue = items.Sum(i => i.Price);
Guard.Against.Condition(totalItemValue == amount,
nameof(amount), "Amount must match total item value");
// Process the order...
}
Use custom conditions to validate complex business rules and domain-specific constraints.
public void TransferFunds(decimal amount, Account fromAccount,
Account toAccount)
{
Guard.Against.NegativeOrZero(amount);
Guard.Against.Null(fromAccount);
Guard.Against.Null(toAccount);
// Business rule: Sufficient funds
Guard.Against.Condition(
fromAccount.Balance >= amount,
nameof(amount),
$"Insufficient funds. Available: {fromAccount.Balance}, Requested: {amount}"
);
// Business rule: Different accounts
Guard.Against.Condition(
fromAccount.Id != toAccount.Id,
nameof(toAccount),
"Cannot transfer to the same account"
);
// Business rule: Account status
Guard.Against.Condition(
fromAccount.Status == AccountStatus.Active &&
toAccount.Status == AccountStatus.Active,
nameof(fromAccount),
"Both accounts must be active"
);
// Perform transfer...
}
Follow these guidelines to get the most out of Guardian in your applications.
Place guards at the beginning of methods to fail fast and provide clear error messages.
Use the most specific guard clause available for better error messages and clearer intent.
Add custom error messages for domain-specific validations to help with debugging.
Use multiple guard clauses together for comprehensive parameter validation.
Use guards consistently across your codebase for predictable behavior.
Avoid excessive guards in performance-critical loops where validation has already occurred.
Guards are for parameter validation, not complex business rule enforcement.
Always use the return value from guard methods as they may modify the input.
Let Guardian throw appropriate exception types rather than catching and re-throwing.
Document complex guard conditions to help other developers understand the constraints.
Guardian is designed for minimal performance impact in production applications.
No memory allocations when validation passes
Methods optimized for JIT compilation
Prevents boxing of value types
Fast execution when validation succeeds
Guardian supports all modern .NET platforms and framework versions.
Full support for latest .NET versions
Compatibility with .NET Framework 4.6.1+
CallerArgumentExpression and nullable references
No external package dependencies
Start using Guardian today and make your .NET applications more robust with comprehensive parameter validation.