如何强制数字在C#范围内?

Ars*_*nko 31 .net c# math performance

在C#中,我经常要将整数值限制为一系列值.例如,如果应用程序需要百分比,则用户输入中的整数不得小于零或大于一百.另一个例子:如果有五个网页可以访问Request.Params["p"],我希望值为1到5,而不是0或256或99999.

我常常写一个非常丑陋的代码,如:

page = Math.Max(0, Math.Min(2, page));
Run Code Online (Sandbox Code Playgroud)

甚至是丑陋的:

percentage =
    (inputPercentage < 0 || inputPercentage > 100) ?
    0 :
    inputPercentage;
Run Code Online (Sandbox Code Playgroud)

在.NET Framework中没有更智能的方法来做这些事情吗?

我知道我可以编写一个通用的方法int LimitToRange(int value, int inclusiveMinimum, int inlusiveMaximum)并在每个项目中使用它,但也许框架中已经有一个神奇的方法了?

如果我需要手动执行,那么在第一个示例中执行我正在执行的操作的"最佳"(即,更简单,更快速)的方法是什么?像这样的东西?

public int LimitToRange(int value, int inclusiveMinimum, int inlusiveMaximum)
{
    if (value >= inclusiveMinimum)
    {
        if (value <= inlusiveMaximum)
        {
            return value;
        }

        return inlusiveMaximum;
    }

    return inclusiveMinimum;
}
Run Code Online (Sandbox Code Playgroud)

Tra*_*rap 56

这个操作叫做'Clamp',它通常写成:

public static int Clamp( int value, int min, int max )
{
    return (value < min) ? min : (value > max) ? max : value;
}
Run Code Online (Sandbox Code Playgroud)

  • PS.使用<=和> =而不是<和>,此代码更有效.:-) (7认同)
  • 我喜欢Clamp这个名字.甚至Microsoft.Xna.Framework都有一个Clamp方法:) (3认同)
  • Clamp是正常名称.请参阅OpenCL规范. (3认同)
  • 添加“this”,您可以将其用作扩展方法: public static int Clamp(this int value, int min, int max ) { return (value &lt; min) ? 最小值:(值 &gt; 最大值)?最大值:值;现在你可以说: myInt.Clamp(10,50); (2认同)
  • 从 .NET Standard 2.1 (Core 2.0) 开始,内置了 [Math.Clamp()](https://learn.microsoft.com/en-us/dotnet/api/system.math.clamp) 方法。 (2认同)

dtb*_*dtb 27

我看到马克的答案,并通过以下方式提出this:

public static class InputExtensions
{
    public static int LimitToRange(
        this int value, int inclusiveMinimum, int inclusiveMaximum)
    {
        if (value < inclusiveMinimum) { return inclusiveMinimum; }
        if (value > inclusiveMaximum) { return inclusiveMaximum; }
        return value;
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

int userInput = ...;

int result = userInput.LimitToRange(1, 5)
Run Code Online (Sandbox Code Playgroud)

请参阅:扩展方法

  • 请注意,使用扩展方法不一定是好事.它只是另一种编程工具,它有其用途.把它放在错误的地方或上下文中,你最终会编写不可读的代码. (4认同)

Mik*_*keP 27

一个更简洁的方法,不仅可以使用整数(取自我自己的共享代码库):

public static T Clamp<T>(T value, T min, T max) where T : IComparable<T>
{
    if (value.CompareTo(min) < 0)
        return min;
    if (value.CompareTo(max) > 0)
        return max;

    return value;
}
Run Code Online (Sandbox Code Playgroud)

  • 如果`value`为`null`,则抛出NullReferenceException.最好使用IComparer <T>(例如`Comparer <T> .Default`).http://msdn.microsoft.com/en-us/library/azhsac5f.aspx (12认同)

Mar*_*ers 7

编写LimitToRange函数的另一种方法如下.

public int LimitToRange(int value, int inclusiveMinimum, int inclusiveMaximum)
{
    if (value < inclusiveMinimum) { return inclusiveMinimum; }
    if (value > inclusiveMaximum) { return inclusiveMaximum; }
    return value;
}
Run Code Online (Sandbox Code Playgroud)

我认为这仍然有效,但更容易理解.

  • @MainMa:如果值在范围内,则无论您将语句放在哪个顺序,都必须执行两次检查.在性能方面,所有答案应该是平等的. (3认同)
  • 使用 &lt;= 和 &gt;= 可以避免第二次检查或在边缘情况下跳转:-) (2认同)

Ed *_* S. 7

我喜欢Guffa的回答,但我很惊讶没有人使用Min/Max发布解决方案.

public int LimitInclusive(int value, int min, int max)
{
    return Math.Min(max, Math.Max(value, min));
}
Run Code Online (Sandbox Code Playgroud)