I'm looking for a way to guard against arguments that are out of range, something along the lines of...
public static class Guard {
public static void AgainstOutOfRange<TArgument>(TArgument argument,
TArgument minInclusive, TArgument maxInclusive)
where TArgument : struct, IComparable<TArgument>, IConvertible
{
if(argument.CompareTo ????
}
Looking for 'numeric constraints' on generics I stumpled upon this where @Lee suggests
public static bool IsGreaterThan<T>(this T actual, T comp) where T : IComparable<T>
{
return actual.CompareTo(comp) > 0;
}
I'm however not sure if this is inclusive, exclusive and how to check for 'IsSmallerThan' (I do not fully understand IComparable
yet)
Guard.AgainstOutOfRange(5, 0, 5)
should accept 5
as a valid argument, since we're allowing 0
to 5
inclusive.Guard.ArgumentOutOfRange(5, 0, 5)
should reject 5
as a valid argument, since we're not allowing the upper and lower bounds themselves as valid values.With that in mind, I think you're just looking for:
if(argument.CompareTo(minInclusive) < 0 ||
argument.CompareTo(maxInclusive) > 0)
{
throw new ArgumentException("Argument out of range");
}
Here we're saying:
argument
to minInclusive
is less than zero (argument
is less than minInclusive
) ORargument
to maxInclusive
is greater than zero (argument
is greater than maxInclusive
)... Then we have an invalid argument. Note that if the comparison is equal to zero in either case, we treat that as an valid argument (zero is not greater than or less than zero, so it passes our test).
If we were to make our test exclusive, we could include the result of CompareTo
equaling zero in our check:
if(argument.CompareTo(minInclusive) <= 0 ||
argument.CompareTo(maxInclusive) >= 0)
{
throw new ArgumentException("Argument out of range");
}
Then we'd be saying if the parameter is equal to the lower or upper bound, that's an invalid argument too.
The documentation for IComparable.CompareTo
explains the result of instance.CompareTo(obj)
:
Less than zero This instance precedes obj in the sort order.
Zero: This instance occurs in the same position in the sort order as obj.
Greater than zero: This instance follows obj in the sort order.