Guard Methods
SGuard provides two complementary sets of guard methods for validation.
The Two APIs
ThrowIf.* (Exception Throwing)
Fail fast by throwing informative exceptions when validation fails.
ThrowIf.NullOrEmpty(user.Email);
ThrowIf.LessThan(age, 0);
ThrowIf.Between(value, min, max); // Throws if value IS between min and max
When to use:
- Input validation at method boundaries
- Constructor validation
- Enforcing invariants that must never be violated
Is.* (Boolean Returns)
Return boolean values for control-flow-friendly checks.
if (Is.Between(value, min, max))
{
// value is in range
}
bool isValid = Is.LessThan(a, b);
When to use:
- Conditional logic and branching
- Validation with custom error handling
- When you need to check multiple conditions before acting
Available Guard Methods
Null/Empty Validation
NullOrEmpty: Checks fornull,""(whitespace is not empty), empty collections and arrays, and default values of value types (0,false,Guid.Empty,default(DateTime), ...). A non-null class instance is never considered empty on its own; its properties are not inspected.- Selectors: Check a member of an object (e.g.,
ThrowIf.NullOrEmpty(order, o => o.Customer.Name)). Anullanywhere on the path counts as empty. When the selected member is itself a complex object, it counts as empty only if all of its readable properties are null or empty.
ThrowIf.NullOrEmpty(str);
ThrowIf.NullOrEmpty(list);
ThrowIf.NullOrEmpty(obj, x => x.Property);
bool isEmpty = Is.NullOrEmpty(collection);
Comparison Guards
All comparison guards are generic (TLeft : IComparable<TRight>). Overloads that take a StringComparison exist
for Is.LessThan, Is.LessThanOrEqual, Is.GreaterThan, Is.GreaterThanOrEqual, Is.Between and
ThrowIf.Between only; the other ThrowIf.* comparisons have no StringComparison overload.
LessThan:value < otherLessThanOrEqual:value <= otherGreaterThan:value > otherGreaterThanOrEqual:value >= otherBetween: Inclusive range check (min <= value <= max)
ThrowIf.LessThan(age, 0);
ThrowIf.Between(value, 10, 20); // Throws if 10 <= value <= 20
bool inRange = Is.Between(score, 0, 100);
bool isLess = Is.LessThan("apple", "banana", StringComparison.Ordinal);
The left operand's type decides the comparison, so literals must match it: for a decimal use 0m, not 0
(decimal does not implement IComparable<int>).
NaN: if any operand is a floating-point NaN (double, float, Half), Is.* comparisons return false and
ThrowIf.* comparisons throw. A check written as if (Is.GreaterThan(x, max)) reject(); therefore lets NaN
through; prefer ThrowIf.* or !Is.Between(x, min, max) for bound checks.
Collection Guards
Predicate-based validation for collections:
Any: At least one element matches the predicateAll: All elements match the predicate
ThrowIf.Any(items, i => i is null);
ThrowIf.All(numbers, n => n < 0); // Throws if all numbers are negative
bool hasPositive = Is.Any(numbers, n => n > 0);
bool allValid = Is.All(items, i => i.IsValid());
On an empty collection they follow LINQ: Is.All returns true and Is.Any returns false. So
ThrowIf.All(empty, ...) throws and ThrowIf.Any(empty, ...) does not.
Guard Semantics
Between is Inclusive
The Between guard uses inclusive comparisons by design:
Is.Between(5, 1, 10); // true (5 is between 1 and 10, inclusive)
Is.Between(1, 1, 10); // true (min is allowed)
Is.Between(10, 1, 10); // true (max is allowed)
For ThrowIf.Between, it throws if the value is within the range:
ThrowIf.Between(5, 1, 10); // Throws (5 is in range)
ThrowIf.Between(0, 1, 10); // Does NOT throw (0 is outside range)
CallerArgumentExpression
SGuard uses CallerArgumentExpression to automatically capture argument names:
ThrowIf.NullOrEmpty(user.Email);
// NullOrEmptyException: "Value 'user.Email' is null or empty."
// ex.ParamName == "user.Email"
The built-in exceptions derive from ArgumentException. Messages name the expressions but leave out the checked
values unless you enable SGuardOptions.IncludeValuesInExceptions (see
Custom Exceptions).
No manual parameter name strings required!
Next Steps
- Callbacks - Add side effects on success/failure
- Custom Exceptions - Use your own exception types
- API Reference - Complete method signatures