ComparableExtensions Class
Definition
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
valueTThe value to coerce.
minTThe inclusive lower bound.
Returns
- T
valueif it compares greater than or equal tomin; otherwise,min.
Type Parameters
TThe 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
valueTThe value to coerce.
minTThe inclusive lower bound.
comparerIComparer<T>The comparer to use for comparing values.
Returns
- T
valueif it compares greater than or equal tominunder the specified comparer; otherwise,min.
Type Parameters
TThe 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
compareris 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
valueTThe value to coerce.
maxTThe inclusive upper bound.
Returns
- T
valueif it compares less than or equal tomax; otherwise,max.
Type Parameters
TThe 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
valueTThe value to coerce.
maxTThe inclusive upper bound.
comparerIComparer<T>The comparer to use for comparing values.
Returns
- T
valueif it compares less than or equal tomaxunder the specified comparer; otherwise,max.
Type Parameters
TThe 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
compareris 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
valueTThe value to clamp.
minT?The inclusive minimum bound, or null for no lower bound.
maxT?The inclusive maximum bound, or null for no upper bound.
Returns
- T
The clamped value. If
valueis less thanmin,minis returned. Ifvalueis greater thanmax,maxis returned. Otherwise,valueis returned.
Type Parameters
TThe 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
minis greater thanmax, 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
valueTThe value to clamp.
minT?The inclusive minimum bound, or null for no lower bound.
maxT?The inclusive maximum bound, or null for no upper bound.
comparerIComparer<T>The comparer to use for comparing the values.
Returns
- T
The clamped value. If
valueis less thanmin,minis returned. Ifvalueis greater thanmax,maxis returned. Otherwise,valueis returned.
Type Parameters
TThe 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
compareris null.- ArgumentException
Thrown when both bounds are supplied and
minorders aftermaxaccording tocomparer.
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
valueTThe value to test.
value1T?The first boundary.
value2T?The second boundary.
comparerIComparer<T>The comparer to use for comparing values.
Returns
- bool
true if
valuefalls betweenvalue1andvalue2inclusively based on the specified comparer; otherwise, false.
Type Parameters
TThe 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
compareris 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
valueTThe value to test.
value1TThe first boundary.
value2TThe second boundary.
Returns
Type Parameters
TThe type of the value to compare, which must implement IComparable<T>.
Remarks
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
valueTThe first value.
otherTThe second value.
comparerIComparer<T>The comparer whose ordering is used to determine equality.
Returns
- bool
true if
comparercomparesvalueandotheras equal (that is, Compare(T, T) returns zero); otherwise, false.
Type Parameters
TThe 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
compareris 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
valueTThe value to test.
otherT?The reference value to compare against.
comparerIComparer<T>The comparer to use for comparing values.
Returns
- bool
true if
valueis greater than or equal tootherbased on the specified comparer; otherwise, false.
Type Parameters
TThe type of the value to compare.
Remarks
Exceptions
- ArgumentNullException
Thrown when
compareris 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
valueTThe value to test.
otherTThe reference value to compare against.
Returns
Type Parameters
TThe type of the value to compare, which must implement IComparable<T>.
Remarks
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
valueTThe value to test.
otherT?The reference value to compare against.
comparerIComparer<T>The comparer to use for comparing values.
Returns
- bool
true if
valueis strictly greater thanotherbased on the specified comparer; otherwise, false.
Type Parameters
TThe type of the value to compare.
Remarks
Exceptions
- ArgumentNullException
Thrown when
compareris 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
valueTThe value to test.
otherTThe reference value to compare against.
Returns
Type Parameters
TThe type of the value to compare, which must implement IComparable<T>.
Remarks
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
valueTThe value to test.
otherT?The reference value to compare against.
comparerIComparer<T>The comparer to use for comparing values.
Returns
- bool
true if
valueis less than or equal tootherbased on the specified comparer; otherwise, false.
Type Parameters
TThe type of the value to compare.
Remarks
Exceptions
- ArgumentNullException
Thrown when
compareris 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
valueTThe value to test.
otherTThe reference value to compare against.
Returns
Type Parameters
TThe type of the value to compare, which must implement IComparable<T>.
Remarks
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
valueTThe value to test.
otherT?The reference value to compare against.
comparerIComparer<T>The comparer to use for comparing values.
Returns
Type Parameters
TThe type of the value to compare.
Remarks
Exceptions
- ArgumentNullException
Thrown when
compareris 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
valueTThe value to test.
otherTThe reference value to compare against.
Returns
Type Parameters
TThe type of the value to compare, which must implement IComparable<T>.
Remarks
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
valueTThe value to test.
value1T?The first boundary.
value2T?The second boundary.
comparerIComparer<T>The comparer to use for comparing values.
Returns
- bool
trueifvalueis less than the smaller boundary or greater than the larger boundary based on the specified comparer; otherwise,false.
Type Parameters
TThe 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
compareris 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
valueTThe value to test.
value1TThe first boundary.
value2TThe second boundary.
Returns
- bool
trueifvalueis less than the smaller boundary or greater than the larger boundary; otherwise,false.
Type Parameters
TThe 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
valueTThe first value.
otherTThe second value.
Returns
- T
valueif it compares greater than or equal toother; otherwise,other.
Type Parameters
TThe 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
valueTThe first value.
otherTThe second value.
comparerIComparer<T>The comparer to use for comparing values.
Returns
- T
valueif it compares greater than or equal tootherunder the specified comparer; otherwise,other.
Type Parameters
TThe type of the values to compare.
Remarks
When the two values compare equal under comparer, value is returned.
Exceptions
- ArgumentNullException
Thrown when
compareris 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
valueTThe first value.
otherTThe second value.
Returns
- T
valueif it compares less than or equal toother; otherwise,other.
Type Parameters
TThe 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
valueTThe first value.
otherTThe second value.
comparerIComparer<T>The comparer to use for comparing values.
Returns
- T
valueif it compares less than or equal tootherunder the specified comparer; otherwise,other.
Type Parameters
TThe type of the values to compare.
Remarks
When the two values compare equal under comparer, value is returned.
Exceptions
- ArgumentNullException
Thrown when
compareris null.
Applies to
| Product | Versions |
|---|---|
| .NET | 8, 10 |