How can I do this elegantly with C# and .NET 3.5/4?
For example, a number can be between 1 and 100.
I know a simple if would suffice; but the keyword to this
If you are concerned with the comment by @Daap on the accepted answer and can only pass the value once, you could try one of the following
bool TestRangeDistance (int numberToCheck, int bottom, int distance)
{
return (numberToCheck >= bottom && numberToCheck <= bottom+distance);
}
//var t = TestRangeDistance(10, somelist.Count()-5, 10);
or
bool TestRangeMargin (int numberToCheck, int target, int margin)
{
return (numberToCheck >= target-margin && numberToCheck <= target+margin);
}
//var t = TestRangeMargin(10, somelist.Count(), 5);
I was looking for an elegant way to do it where the bounds might be switched (ie. not sure which order the values are in).
This will only work on newer versions of C# where the ?: exists
bool ValueWithinBounds(float val, float bounds1, float bounds2)
{
return bounds1 >= bounds2 ?
val <= bounds1 && val >= bounds2 :
val <= bounds2 && val >= bounds1;
}
Obviously you could change the = signs in there for your purposes. Could get fancy with type casting too. I just needed a float return within bounds (or equal to)
If this is incidental, a simple if
is all you need. If this happens in many places, you might want to consider these two:
Something like:
[Between("parameter", 0, 100)]
public void Foo(int parameter)
{
}
I don't know but i use this method:
public static Boolean isInRange(this Decimal dec, Decimal min, Decimal max, bool includesMin = true, bool includesMax = true ) {
return (includesMin ? (dec >= min) : (dec > min)) && (includesMax ? (dec <= max) : (dec < max));
}
And this is the way I can use it:
[TestMethod]
public void IsIntoTheRange()
{
decimal dec = 54;
Boolean result = false;
result = dec.isInRange(50, 60); //result = True
Assert.IsTrue(result);
result = dec.isInRange(55, 60); //result = False
Assert.IsFalse(result);
result = dec.isInRange(54, 60); //result = True
Assert.IsTrue(result);
result = dec.isInRange(54, 60, false); //result = False
Assert.IsFalse(result);
result = dec.isInRange(32, 54, false, false);//result = False
Assert.IsFalse(result);
result = dec.isInRange(32, 54, false);//result = True
Assert.IsTrue(result);
}
if (value > 1 && value < 100)
{
// do work
}
else
{
// handle outside of range logic
}
I would do a Range object, something like this:
public class Range<T> where T : IComparable
{
public T InferiorBoundary{get;private set;}
public T SuperiorBoundary{get;private set;}
public Range(T inferiorBoundary, T superiorBoundary)
{
InferiorBoundary = inferiorBoundary;
SuperiorBoundary = superiorBoundary;
}
public bool IsWithinBoundaries(T value){
return InferiorBoundary.CompareTo(value) > 0 && SuperiorBoundary.CompareTo(value) < 0;
}
}
Then you use it this way:
Range<int> myRange = new Range<int>(1,999);
bool isWithinRange = myRange.IsWithinBoundaries(3);
That way you can reuse it for another type.