Validation
Fluent extension methods for validating inputs inline. All methods throw a
descriptive exception on failure and return the value on success, enabling
chaining. Parameter names are captured automatically via
[CallerArgumentExpression] — no nameof() needed.
When a validation method throws, the exception message includes the parameter
name inferred from the call-site expression. Passing an explicit
paramName overrides this behaviour.
Any Type
EnsureNotNull<T>
Validates that a reference-type value is not null. Returns the non-null value, allowing use in a fluent assignment.
Signature
public static T EnsureNotNull<T>(
this T? value,
[CallerArgumentExpression("value")] string? paramName = null
) where T : class
Parameters
| Name | Type | Description |
|---|---|---|
| value | T? | The value to check. |
| paramName | string? | Optional override for the parameter name used in the exception message. Captured automatically if omitted. |
Returns & Throws
| Outcome | Detail |
|---|---|
| Returns T | The non-null value. |
| ArgumentNullException | Thrown when value is null. |
Examples
// Guard at the top of a method
public void ProcessOrder(Order? order)
{
order.EnsureNotNull(); // throws ArgumentNullException("order") if null
// safe to use order beyond this point
}
// Inline assignment — value guaranteed non-null
User user = GetUser(id).EnsureNotNull();
// Explicit param name
string result = input.EnsureNotNull(paramName: "input");
EnsureArrayWithinMaxLength<T>
Validates that an array does not exceed a maximum length.
Null arrays and null/negative maxLength values are treated as valid.
Signature
public static T[]? EnsureArrayWithinMaxLength<T>(
this T[]? array,
int maxLength,
[CallerArgumentExpression("array")] string? paramName = null
)
Parameters
| Name | Type | Description |
|---|---|---|
| array | T[]? | The array to validate. Null arrays are allowed. |
| maxLength | int | The maximum permitted number of elements. Negative or null-equivalent values are ignored. |
| paramName | string? | Auto-captured parameter name override. |
Returns & Throws
| Outcome | Detail |
|---|---|
| Returns T[]? | The array if null or within length. |
| ArgumentException | Thrown when array length exceeds maxLength. |
Example
public void UploadFiles(string[]? filePaths)
{
filePaths.EnsureArrayWithinMaxLength(10);
// proceed with up to 10 files
}
string[] tags = GetTags();
tags.EnsureArrayWithinMaxLength(5); // max 5 tags allowed
EnsureIsValid<T>
Validates that a model implementing
IValidatable is in a valid
state. Null models are allowed and returned as-is.
Signature
public static T? EnsureIsValid<T>(
this T? model,
[CallerArgumentExpression("model")] string? paramName = null
) where T : class, IValidatable
Returns & Throws
| Outcome | Detail |
|---|---|
| Returns T? | The model if null or valid. |
| ArgumentException | Thrown when model.IsValid() returns false. The exception message includes the error descriptions from model.Errors. |
Example
public Result<User> CreateUser(CreateUserRequest? request)
{
request.EnsureIsValid();
// if request has validation errors, ArgumentException is thrown
// with details from request.Errors
User user = userRepository.Create(request!);
return new Result<User>(user);
}
EnsureNotEqual<T>
Validates that two values are not equal using the default equality comparer. A custom error message can be provided.
Signature
public static T? EnsureNotEqual<T>(
this T? value,
T? comparisonValue,
string? errorMessage = null,
[CallerArgumentExpression("value")] string? parameterName = null
)
Parameters
| Name | Type | Description |
|---|---|---|
| value | T? | The first value. |
| comparisonValue | T? | The value to compare against. |
| errorMessage | string? | Custom message for the exception. Defaults to "Values were found to be equal. Values were {value} and {comparisonValue}". |
| parameterName | string? | Auto-captured parameter name override. |
Returns & Throws
| Outcome | Detail |
|---|---|
| Returns T? | The first value if not equal to the second. |
| ArgumentException | Thrown when values are equal. |
Example
public void UpdateEmail(string currentEmail, string newEmail)
{
newEmail.EnsureNotEqual(
currentEmail,
errorMessage: "The new email must be different from the current email."
);
emailRepository.Update(newEmail);
}
// Works with any comparable type
int newRank = 5;
newRank.EnsureNotEqual(currentRank); // default message if equal
Strings
EnsureWithinMaxLen
Validates that a string does not exceed a maximum character length.
Null strings are allowed. Throws if maxLen is negative.
Signature
public static string? EnsureWithinMaxLen(
this string? value,
int maxLen,
[CallerArgumentExpression("value")] string? paramName = null
)
Returns & Throws
| Outcome | Detail |
|---|---|
| Returns string? | The string if null or within maxLen. |
| ArgumentException | When string length exceeds maxLen, or when maxLen is negative. |
Example
public void SetDisplayName(string? name)
{
name.EnsureWithinMaxLen(50);
this.DisplayName = name;
}
// Chain with other string validators
string? slug = input
.EnsureNotNullEmptyOrWhitespace()
.EnsureWithinMaxLen(100);
EnsureNotEmpty
Validates that a string is not empty ("").
Null strings are allowed and returned unchanged. Whitespace-only strings are not
rejected — use EnsureNotEmptyOrWhitespace for that.
Signature
public static string? EnsureNotEmpty(
this string? value,
[CallerArgumentExpression("value")] string? paramName = null
)
Returns & Throws
| Outcome | Detail |
|---|---|
| Returns string? | The string if null or non-empty. |
| ArgumentException | Thrown when the string is empty. |
Example
public void SetCode(string? code)
{
code.EnsureNotEmpty(); // null is OK, "" is not
this.Code = code;
}
EnsureNotEmptyOrWhitespace
Validates that a string is neither empty nor whitespace-only. Null strings are allowed. Use this when a value is optional but must be meaningful if provided.
Signature
public static string? EnsureNotEmptyOrWhitespace(
this string? value,
[CallerArgumentExpression("value")] string? paramName = null
)
Returns & Throws
| Outcome | Detail |
|---|---|
| Returns string? | The string if null or contains non-whitespace characters. |
| ArgumentException | Thrown when the string is empty or contains only whitespace. |
Example
// Optional nickname — null is fine, " " is not
public void SetNickname(string? nickname)
{
nickname.EnsureNotEmptyOrWhitespace();
this.Nickname = nickname;
}
EnsureNotNullEmptyOrWhitespace
The strictest string validator. Rejects null, empty, and whitespace-only
strings. Returns a non-nullable string, eliminating the need for a
null-forgiving operator on the result.
Signature
public static string EnsureNotNullEmptyOrWhitespace(
this string? value,
[CallerArgumentExpression("value")] string? paramName = null
)
Returns & Throws
| Outcome | Detail |
|---|---|
| Returns string | The value as a non-nullable string. |
| ArgumentNullException | Thrown when the string is null. |
| ArgumentException | Thrown when the string is empty or whitespace-only. |
Examples
public void SetUsername(string? username)
{
// Returns non-nullable string — no ! needed
string validated = username.EnsureNotNullEmptyOrWhitespace();
this.Username = validated;
}
// Common pattern: validate at the top of a constructor
public User(string? name, string? email)
{
Name = name.EnsureNotNullEmptyOrWhitespace();
Email = email.EnsureNotNullEmptyOrWhitespace();
}
// All three rejected inputs:
// null → ArgumentNullException("username")
// "" → ArgumentException("username")
// " " → ArgumentException("username")
Numerics
EnsureBetween
Validates that an integer falls within an inclusive range.
Throws if the value is outside the range or if the range definition is invalid
(i.e. startOfRange > endOfRange).
Signature
public static int EnsureBetween(
this int value,
int startOfRange,
int endOfRange,
[CallerArgumentExpression("value")] string? paramName = null
)
Parameters
| Name | Type | Description |
|---|---|---|
| value | int | The value to validate. |
| startOfRange | int | Inclusive lower bound of the valid range. |
| endOfRange | int | Inclusive upper bound of the valid range. |
| paramName | string? | Auto-captured parameter name override. |
Returns & Throws
| Outcome | Detail |
|---|---|
| Returns int | The value if within range. |
| ArgumentException | Thrown when value is outside the range, or when startOfRange > endOfRange. Message: "Value must be between {start} and {end}. Value was {value}." |
Examples
// Guard age in a registration method
public void Register(string? name, int age)
{
name.EnsureNotNullEmptyOrWhitespace();
age.EnsureBetween(18, 120);
// proceed safely
}
// Validate a percentage
public void SetProgress(int percentage)
{
percentage.EnsureBetween(0, 100);
this.Progress = percentage;
}
// Validate a priority level (1–5)
public void SetPriority(int priority)
{
priority.EnsureBetween(1, 5);
this.Priority = priority;
}