Table of Contents

ComparableExtensions Class

Definition

Namespace
Bodu.Extensions
Assembly
Bodu.Core.dll
Package
Bodu.Core 1.0.1
Source
ComparableExtensions.AtLeast.cs

Provides predicate, clamping, and selection operations over any IComparable<T> value, turning common "is this within the expected window?" and "pick the better candidate" decisions into one-liners that read naturally.

public static class ComparableExtensions
Inheritance
ComparableExtensions
Inherited Members

Remarks

Range checks and bounded arithmetic are some of the most repeated patterns in business code, yet expressing them with raw CompareTo(T) is verbose and easy to get wrong (off-by-one boundaries, swapped arguments, missing IComparer<T> threads). This class wraps those checks behind verb-led names that match the way callers describe the intent - IsBetween, IsOutside, AtLeast, AtMost, Clamp, Min, Max - so the call site reads as a fluent assertion rather than a comparison expression.

The API surface is split into three groups: comparison predicates (IsLessThan, IsLessThanOrEqual, IsGreaterThan, IsGreaterThanOrEqual, IsEqualTo), windowed predicates (IsBetween, IsOutside), and value-shaping helpers that produce a result rather than a boolean (AtLeast, AtMost, Clamp, Min, Max). Each method is offered with a default overload that uses the type's natural ordering and a paired overload that accepts an explicit IComparer<T>, so callers can opt into culture-aware string comparisons or domain-specific orderings without rewriting the call.

All methods are pure, allocation-free, and deterministic. The default-comparer overloads use Default, which itself defers to IComparable<T> when implemented; if the type is not orderable an InvalidOperationException bubbles up from the underlying comparer. Boundary inclusivity follows the inclusive convention: IsBetween includes both endpoints, and Clamp returns the boundary value rather than throwing when the input is outside.

The comparer-accepting overloads of the range predicates ( IsBetween, IsOutside) and Clamp are constrained to value types; for reference-type operands use the default-comparer overloads, or the two-operand ordering helpers on ComparableHelper.

int volume = 11;

// Replace explicit min/max calls with a fluent clamp.
int safeVolume = volume.Clamp(0, 10); // => 10

// Inclusive "between" predicate, ideal in guard clauses.
bool inDecimalDigits = '7'.IsBetween('0', '9'); // => true

// Custom comparer: a reversed ordering legitimately accepts inverted bounds.
var descending = Comparer<int>.Create((x, y) => y.CompareTo(x));
bool inCountdown = 5.IsBetween(10, 1, descending); // => true

Methods

AtLeast<T>(T, T)

Raises a value to a specified inclusive lower bound, returning the bound when the value falls below it.

public static T AtLeast<T>(this T value, T min) where T : IComparable<T>

Parameters

value T

The value to coerce.

min T

The inclusive lower bound.

Returns

T

value if it compares greater than or equal to min; otherwise, min.

Type Parameters

T

The type of the value to coerce, which must implement IComparable<T>.

Remarks

This is a one-sided form of Clamp<T>(T, T?, T?) for cases where only a floor is required. Equivalent to Math.Max(value, min) for numeric types.

AtLeast<T>(T, T, IComparer<T>)

Raises a value to a specified inclusive lower bound using a custom IComparer<T>.

public static T AtLeast<T>(this T value, T min, IComparer<T> comparer)

Parameters

value T

The value to coerce.

min T

The inclusive lower bound.

comparer IComparer<T>

The comparer to use for comparing values.

Returns

T

value if it compares greater than or equal to min under the specified comparer; otherwise, min.

Type Parameters

T

The type of the value to coerce.

Remarks

This is a one-sided form of Clamp<T>(T, T?, T?, IComparer<T>) for cases where only a floor is required.

Exceptions

ArgumentNullException

Thrown when comparer is null.

AtMost<T>(T, T)

Lowers a value to a specified inclusive upper bound, returning the bound when the value exceeds it.

public static T AtMost<T>(this T value, T max) where T : IComparable<T>

Parameters

value T

The value to coerce.

max T

The inclusive upper bound.

Returns

T

value if it compares less than or equal to max; otherwise, max.

Type Parameters

T

The type of the value to coerce, which must implement IComparable<T>.

Remarks

This is a one-sided form of Clamp<T>(T, T?, T?) for cases where only a ceiling is required. Equivalent to Math.Min(value, max) for numeric types.

AtMost<T>(T, T, IComparer<T>)

Lowers a value to a specified inclusive upper bound using a custom IComparer<T>.

public static T AtMost<T>(this T value, T max, IComparer<T> comparer)

Parameters

value T

The value to coerce.

max T

The inclusive upper bound.

comparer IComparer<T>

The comparer to use for comparing values.

Returns

T

value if it compares less than or equal to max under the specified comparer; otherwise, max.

Type Parameters

T

The type of the value to coerce.

Remarks

This is a one-sided form of Clamp<T>(T, T?, T?, IComparer<T>) for cases where only a ceiling is required.

Exceptions

ArgumentNullException

Thrown when comparer is null.

Clamp<T>(T, T?, T?)

Restricts a value to lie within a specified inclusive range.

public static T Clamp<T>(this T value, T? min, T? max) where T : struct, IComparable<T>

Parameters

value T

The value to clamp.

min T?

The inclusive minimum bound, or null for no lower bound.

max T?

The inclusive maximum bound, or null for no upper bound.

Returns

T

The clamped value. If value is less than min, min is returned. If value is greater than max, max is returned. Otherwise, value is returned.

Type Parameters

T

The type of the value to clamp, which must implement IComparable<T>.

Remarks

If min or max is null, the corresponding bound is treated as unbounded and no bound-ordering validation is performed for that side.

Exceptions

ArgumentException

Thrown when both bounds are supplied and min is greater than max, matching the behavior of Clamp(int, int, int).

Clamp<T>(T, T?, T?, IComparer<T>)

Restricts a value to lie within a specified inclusive range using a custom IComparer<T>.

public static T Clamp<T>(this T value, T? min, T? max, IComparer<T> comparer) where T : struct

Parameters

value T

The value to clamp.

min T?

The inclusive minimum bound, or null for no lower bound.

max T?

The inclusive maximum bound, or null for no upper bound.

comparer IComparer<T>

The comparer to use for comparing the values.

Returns

T

The clamped value. If value is less than min, min is returned. If value is greater than max, max is returned. Otherwise, value is returned.

Type Parameters

T

The type of the value to clamp.

Remarks

If min or max is null, the corresponding bound is treated as unbounded and no bound-ordering validation is performed for that side. Use this overload to apply custom comparison logic when clamping values; the bound-ordering check uses comparer, so a reversed comparer legitimately accepts bounds whose natural ordering is inverted.

Exceptions

ArgumentNullException

Thrown when comparer is null.

ArgumentException

Thrown when both bounds are supplied and min orders after max according to comparer.

IsBetween<T>(T, T?, T?, IComparer<T>)

Determines whether a value falls inclusively between two specified boundaries using a custom IComparer<T>.

public static bool IsBetween<T>(this T value, T? value1, T? value2, IComparer<T> comparer) where T : struct

Parameters

value T

The value to test.

value1 T?

The first boundary.

value2 T?

The second boundary.

comparer IComparer<T>

The comparer to use for comparing values.

Returns

bool

true if value falls between value1 and value2 inclusively based on the specified comparer; otherwise, false.

Type Parameters

T

The type of the value to compare.

Remarks

If value1 or value2 is null, the method returns false.

The order of value1 and value2 does not matter.

Exceptions

ArgumentNullException

Thrown when comparer is null.

IsBetween<T>(T, T?, T?)

Determines whether a value falls inclusively between two specified boundaries.

public static bool IsBetween<T>(this T value, T? value1, T? value2) where T : IComparable<T>

Parameters

value T

The value to test.

value1 T

The first boundary.

value2 T

The second boundary.

Returns

bool

true if value falls between value1 and value2 inclusively; otherwise, false.

Type Parameters

T

The type of the value to compare, which must implement IComparable<T>.

Remarks

If any parameter is null, the method returns false.

The order of value1 and value2 does not matter.

IsEqualTo<T>(T, T, IComparer<T>)

Determines whether two values are equal under the ordering defined by a custom IComparer<T>.

public static bool IsEqualTo<T>(this T value, T other, IComparer<T> comparer)

Parameters

value T

The first value.

other T

The second value.

comparer IComparer<T>

The comparer whose ordering is used to determine equality.

Returns

bool

true if comparer compares value and other as equal (that is, Compare(T, T) returns zero); otherwise, false.

Type Parameters

T

The type of the values to compare.

Remarks

Comparer-defined equality is distinct from Equals(object). A case-insensitive StringComparer, for example, considers "Hello" and "hello" equal even though Equals(string) does not. For the default equality semantics of T use Equals(object) or Equals(T) directly.

Exceptions

ArgumentNullException

Thrown when comparer is null.

IsGreaterThanOrEqual<T>(T, T?, IComparer<T>)

Determines whether a value is greater than or equal to a specified reference value using a custom IComparer<T>.

public static bool IsGreaterThanOrEqual<T>(this T value, T? other, IComparer<T> comparer) where T : struct

Parameters

value T

The value to test.

other T?

The reference value to compare against.

comparer IComparer<T>

The comparer to use for comparing values.

Returns

bool

true if value is greater than or equal to other based on the specified comparer; otherwise, false.

Type Parameters

T

The type of the value to compare.

Remarks

If other is null, the method returns false.

Exceptions

ArgumentNullException

Thrown when comparer is null.

IsGreaterThanOrEqual<T>(T, T?)

Determines whether a value is greater than or equal to a specified reference value.

public static bool IsGreaterThanOrEqual<T>(this T value, T? other) where T : IComparable<T>

Parameters

value T

The value to test.

other T

The reference value to compare against.

Returns

bool

true if value is greater than or equal to other; otherwise, false.

Type Parameters

T

The type of the value to compare, which must implement IComparable<T>.

Remarks

If other is null, the method returns false.

IsGreaterThan<T>(T, T?, IComparer<T>)

Determines whether a value is strictly greater than a specified reference value using a custom IComparer<T>.

public static bool IsGreaterThan<T>(this T value, T? other, IComparer<T> comparer) where T : struct

Parameters

value T

The value to test.

other T?

The reference value to compare against.

comparer IComparer<T>

The comparer to use for comparing values.

Returns

bool

true if value is strictly greater than other based on the specified comparer; otherwise, false.

Type Parameters

T

The type of the value to compare.

Remarks

If other is null, the method returns false.

Exceptions

ArgumentNullException

Thrown when comparer is null.

IsGreaterThan<T>(T, T?)

Determines whether a value is strictly greater than a specified reference value.

public static bool IsGreaterThan<T>(this T value, T? other) where T : IComparable<T>

Parameters

value T

The value to test.

other T

The reference value to compare against.

Returns

bool

true if value is strictly greater than other; otherwise, false.

Type Parameters

T

The type of the value to compare, which must implement IComparable<T>.

Remarks

If other is null, the method returns false.

IsLessThanOrEqual<T>(T, T?, IComparer<T>)

Determines whether a value is less than or equal to a specified reference value using a custom IComparer<T>.

public static bool IsLessThanOrEqual<T>(this T value, T? other, IComparer<T> comparer) where T : struct

Parameters

value T

The value to test.

other T?

The reference value to compare against.

comparer IComparer<T>

The comparer to use for comparing values.

Returns

bool

true if value is less than or equal to other based on the specified comparer; otherwise, false.

Type Parameters

T

The type of the value to compare.

Remarks

If other is null, the method returns false.

Exceptions

ArgumentNullException

Thrown when comparer is null.

IsLessThanOrEqual<T>(T, T?)

Determines whether a value is less than or equal to a specified reference value.

public static bool IsLessThanOrEqual<T>(this T value, T? other) where T : IComparable<T>

Parameters

value T

The value to test.

other T

The reference value to compare against.

Returns

bool

true if value is less than or equal to other; otherwise, false.

Type Parameters

T

The type of the value to compare, which must implement IComparable<T>.

Remarks

If other is null, the method returns false.

IsLessThan<T>(T, T?, IComparer<T>)

Determines whether a value is strictly less than a specified reference value using a custom IComparer<T>.

public static bool IsLessThan<T>(this T value, T? other, IComparer<T> comparer) where T : struct

Parameters

value T

The value to test.

other T?

The reference value to compare against.

comparer IComparer<T>

The comparer to use for comparing values.

Returns

bool

true if value is strictly less than other based on the specified comparer; otherwise, false.

Type Parameters

T

The type of the value to compare.

Remarks

If other is null, the method returns false.

Exceptions

ArgumentNullException

Thrown when comparer is null.

IsLessThan<T>(T, T?)

Determines whether a value is strictly less than a specified reference value.

public static bool IsLessThan<T>(this T value, T? other) where T : IComparable<T>

Parameters

value T

The value to test.

other T

The reference value to compare against.

Returns

bool

true if value is strictly less than other; otherwise, false.

Type Parameters

T

The type of the value to compare, which must implement IComparable<T>.

Remarks

If other is null, the method returns false.

IsOutside<T>(T, T?, T?, IComparer<T>)

Determines whether a value falls outside the inclusive range defined by two specified boundaries using a custom IComparer<T>.

public static bool IsOutside<T>(this T value, T? value1, T? value2, IComparer<T> comparer) where T : struct

Parameters

value T

The value to test.

value1 T?

The first boundary.

value2 T?

The second boundary.

comparer IComparer<T>

The comparer to use for comparing values.

Returns

bool

true if value is less than the smaller boundary or greater than the larger boundary based on the specified comparer; otherwise, false.

Type Parameters

T

The type of the value to compare.

Remarks

If any of the parameters are null, the method returns false.

The order of value1 and value2 does not matter.

Exceptions

ArgumentNullException

Thrown when comparer is null.

IsOutside<T>(T, T?, T?)

Determines whether a value falls outside the inclusive range defined by two specified boundaries.

public static bool IsOutside<T>(this T value, T? value1, T? value2) where T : IComparable<T>

Parameters

value T

The value to test.

value1 T

The first boundary.

value2 T

The second boundary.

Returns

bool

true if value is less than the smaller boundary or greater than the larger boundary; otherwise, false.

Type Parameters

T

The type of the value to compare, which must implement IComparable<T>.

Remarks

If any of the parameters are null, the method returns false.

The order of value1 and value2 does not matter.

Max<T>(T, T)

Returns the larger of two values using their natural ordering.

public static T Max<T>(this T value, T other) where T : IComparable<T>

Parameters

value T

The first value.

other T

The second value.

Returns

T

value if it compares greater than or equal to other; otherwise, other.

Type Parameters

T

The type of the values to compare, which must implement IComparable<T>.

Remarks

When the two values compare equal, value is returned.

Max<T>(T, T, IComparer<T>)

Returns the larger of two values using a custom IComparer<T>.

public static T Max<T>(this T value, T other, IComparer<T> comparer)

Parameters

value T

The first value.

other T

The second value.

comparer IComparer<T>

The comparer to use for comparing values.

Returns

T

value if it compares greater than or equal to other under the specified comparer; otherwise, other.

Type Parameters

T

The type of the values to compare.

Remarks

When the two values compare equal under comparer, value is returned.

Exceptions

ArgumentNullException

Thrown when comparer is null.

Min<T>(T, T)

Returns the smaller of two values using their natural ordering.

public static T Min<T>(this T value, T other) where T : IComparable<T>

Parameters

value T

The first value.

other T

The second value.

Returns

T

value if it compares less than or equal to other; otherwise, other.

Type Parameters

T

The type of the values to compare, which must implement IComparable<T>.

Remarks

When the two values compare equal, value is returned.

Min<T>(T, T, IComparer<T>)

Returns the smaller of two values using a custom IComparer<T>.

public static T Min<T>(this T value, T other, IComparer<T> comparer)

Parameters

value T

The first value.

other T

The second value.

comparer IComparer<T>

The comparer to use for comparing values.

Returns

T

value if it compares less than or equal to other under the specified comparer; otherwise, other.

Type Parameters

T

The type of the values to compare.

Remarks

When the two values compare equal under comparer, value is returned.

Exceptions

ArgumentNullException

Thrown when comparer is null.

Applies to

ProductVersions
.NET8, 10