Every time I need to prevent a value from going under a minimum or going over a maximum, I have to stop and think about how to use the Math API. If I want to supply a max value, I need to use Math.Min; and conversely, if I want to supply a min value, I need to use Math.Max.

Given int value = 5, if I want to ensure that my value has a minimum of 10, I need to call: Math.Max(value, 10).

Given int value = 500, if I want to ensure that my value has a maximum of 100, I need to call: Math.Min(value, 100).

Yes, these functions do exactly what they say, but the way I always use them makes the API seem backwards. The other day, I decided to solve this problem once and for all. In my scalar extensions class in my project, I added the following methods.

1: /// <summary>

2: /// Return a value that is no less than a minimum

3: /// </summary>

4: public static int ButNoLessThan(this int value, int minimum)

` 5: {`

6: return Math.Max(value, minimum);

` 7: }`

` 8: `

9: /// <summary>

10: /// Return a value that is no more than a maximum

11: /// </summary>

12: public static int ButNotMoreThan(this int value, int maximum)

` 13: {`

14: return Math.Min(value, maximum);

` 15: }`

Here’s a quick illustration:

1: int small = 5;

2: int large = 500;

` 3: `

` 4: Console.WriteLine(small.ButNoLessThan(10));`

` 5: Console.WriteLine(large.ButNotMoreThan(100));`

` 6: `

` 7: Console.WriteLine((small * large).ButNoLessThan(1000).ButNotMoreThan(10000));`

# re: Math.Min and Math.Max are BackwardsYikes, I would hate to see that in a code review. Min and Max are clear, well-understood concepts that have been around for a long time. How do I know what ButNotLessThan means, unless I have read your blog?

I am curious why these two functions are special. When you call Math.Abs, do you try to provide the absolute value? When you call Math.Sign, do you try to provide the sign? It seems odd that only with Min and Max would you try to provide as the argument what the function is telling you that it will return.

# re: Math.Min and Math.Max are BackwardsI believe in the context described, Math.Min and Math.Max are counter-intuitive. Math.Abs and Math.Sign don't bring me pause like Min and Max do. It might just be how my brain is wired, but when I have to stop to think about which of the 2 functions to use for the purpose at hand, then we have room for improvement.

You do bring up a good point though, which is that project-specific extension methods can hinder the familiarity of code to subsequent developers. But extension methods are just helpers and every application accumulates a set of helpers. I assert that small.ButNoLessThan(5) perfectly describes its function.

# re: Math.Min and Math.Max are BackwardsI suppose I'm just not used to seeing wrappers around something as basic as Min and Max. But it is reasonably self explanatory, and if it works for you, who am I to argue.