I'm trying to create a simple Clamp (so that I can bound the values of anything comparable ... mostly for number types such as int, double, etc.)
The problem is if I do the following I get an error, but according to MSDN IComparable's CompareTo is supposed to be able to handle null values.
Quote: "By definition, any object compares greater than null, and two null references compare equal to each other."
public static T Clamp<T>(this T value, T min, T max)
where T : IComparable<T>
{
if (value.CompareTo(max) > 0)
return max;
if (value.CompareTo(min) < 0)
return min;
return value;
}
private Int32? _zip;
public Int32? Zip
{
get
{
return _zip;
}
set
{
_zip = value.Clamp<Int32?>(0, 99999);
}
}
As said by @LBushkin Nullable< T > or T? does not implement IComparable interface. The given solution is ok, however I prefer to have the nullable comparing logic inside a specialized class in that matter, following the Single Responsibility Principle, and also than can be used for comparing any Nullable types.
For example, you could create a generic Nullable type comparer class like this:
public class NullableComparer<T> : IComparer<Nullable<T>>
where T : struct, IComparable<T>
{
public int Compare(Nullable<T> x, Nullable<T> y)
{
//Compare nulls acording MSDN specification
//Two nulls are equal
if (!x.HasValue && !y.HasValue)
return 0;
//Any object is greater than null
if (x.HasValue && !y.HasValue)
return 1;
if (y.HasValue && !x.HasValue)
return -1;
//Otherwise compare the two values
return x.Value.CompareTo(y.Value);
}
}
In this case you would use this class like this:
public static T? Clamp<T>(this T? value, T? min, T? max)
where T : struct
{
var comparer = new NullableComparer<T>();
if (comparer.Compare(value, max) > 0)
return max;
if (comparer.Compare(value, min) < 0)
return min;
return value;
}
Handy for saving in your helpers library.
Hope it helps!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With