Truth vs. Validation

Truth extensions are pure boolean checks — they never throw exceptions. For throwing on invalid input, use the Validation extensions instead.

Collections

None<T>()

Extension

Returns true when a collection is null or contains no elements. A concise, readable alternative to the common null-and-count guard pattern.

Signature

public static bool None<T>(this ICollection<T>? collection)

Parameters

NameTypeDescription
collectionICollection<T>?The collection to inspect. Null is treated as empty.

Returns

ValueWhen
trueCollection is null or has zero elements.
falseCollection has one or more elements.

Examples

// Before Gubbins
if (items == null || items.Count == 0)
{
    return "No items found.";
}

// With Gubbins
if (items.None())
{
    return "No items found.";
}

// Practical: early-exit guard
public Result ProcessOrders(List<Order>? orders)
{
    if (orders.None())
    {
        return new Result("No orders to process.");
    }

    foreach (Order order in orders!)
    {
        ProcessOrder(order);
    }

    return new Result();
}

// Works with any ICollection<T>
ICollection<string>? tags = null;
bool noTags = tags.None(); // true

List<int> emptyList = new List<int>();
bool isEmpty = emptyList.None(); // true

List<int> populated = new List<int> { 1, 2, 3 };
bool hasItems = populated.None(); // false

None<T>(predicate)

Extension

Returns true when a collection is null, empty, or contains no elements that satisfy a predicate. A readable counterpart to !collection.Any(predicate) with added null safety.

Signature

public static bool None<T>(
    this ICollection<T>? collection,
    Func<T, bool> predicate
)

Parameters

NameTypeDescription
collectionICollection<T>?The collection to inspect. Null is treated as empty.
predicateFunc<T, bool>A function that tests each element. Returns true if an element matches.

Returns

ValueWhen
trueCollection is null, empty, or no element satisfies the predicate.
falseAt least one element satisfies the predicate.

Examples

// Before Gubbins
if (users == null || !users.Any(u => u.IsAdmin))
{
    return "No admins available.";
}

// With Gubbins
if (users.None(u => u.IsAdmin))
{
    return "No admins available.";
}

// Check for pending items
List<Order> orders = GetOrders();

if (orders.None(o => o.Status == OrderStatus.Pending))
{
    Console.WriteLine("Nothing to process.");
    return;
}

// Check for overdue tasks
bool noOverdue = tasks.None(t => t.DueDate < DateTime.UtcNow);

// Null-safe — no null check needed first
ICollection<string>? tags = null;
bool noLongTags = tags.None(t => t.Length > 10); // true

Numerics

IsBetween

Extension

Returns true when an integer falls within an inclusive range. A pure boolean check — use EnsureBetween if you want to throw on out-of-range values.

Invalid range definition

If startOfRange is greater than endOfRange, an ArgumentException is thrown as this represents a programming error.

Signature

public static bool IsBetween(
    this int value,
    int startOfRange,
    int endOfRange
)

Parameters

NameTypeDescription
valueintThe integer to test.
startOfRangeintInclusive lower bound. Must be ≤ endOfRange.
endOfRangeintInclusive upper bound. Must be ≥ startOfRange.

Returns & Throws

OutcomeDetail
trueValue is ≥ startOfRange and ≤ endOfRange.
falseValue is outside the range.
ArgumentExceptionThrown when startOfRange > endOfRange.

Examples

// Basic range check
int score = 75;
bool passing = score.IsBetween(50, 100); // true
bool failing = score.IsBetween(0, 49);   // false

// Conditional logic
public string GetRating(int score)
{
    if (score.IsBetween(90, 100)) { return "Excellent"; }
    if (score.IsBetween(70, 89))  { return "Good"; }
    if (score.IsBetween(50, 69))  { return "Average"; }
    return "Below average";
}

// Readable guard clause (non-throwing)
public void ApplyDiscount(int loyaltyPoints)
{
    if (!loyaltyPoints.IsBetween(100, 10000))
    {
        logger.LogWarning("Unexpected loyalty points value: {Points}", loyaltyPoints);
        return;
    }

    ApplyPointsDiscount(loyaltyPoints);
}

// Boundary values are inclusive
5.IsBetween(5, 10);  // true
10.IsBetween(5, 10); // true
4.IsBetween(5, 10);  // false
11.IsBetween(5, 10); // false