在C#中,我经常要将整数值限制为一系列值。例如,如果应用程序需要百分比,则用户输入中的整数不得小于零或大于一百。另一个例子:如果有五个网页可以通过Request.Params["p"]
访问,我希望值为1到5,而不是0或256或99999。
我常常写一个非常难看的代码,如:
page = Math.Max(0, Math.Min(2, page));
甚至更丑陋:
percentage =
(inputPercentage < 0 || inputPercentage > 100) ?
0 :
inputPercentage;
在.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;
}
答案 0 :(得分:53)
此操作称为“Clamp”,它通常写成:
public static int Clamp( int value, int min, int max )
{
return (value < min) ? min : (value > max) ? max : value;
}
答案 1 :(得分:26)
我看到马克的回答,并以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;
}
}
用法:
int userInput = ...;
int result = userInput.LimitToRange(1, 5)
答案 2 :(得分:26)
一个更简洁的方法,不仅可以使用整数(取自我自己的共享代码库):
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;
}
答案 3 :(得分:7)
编写LimitToRange
函数的另一种方法如下:
public int LimitToRange(int value, int inclusiveMinimum, int inclusiveMaximum)
{
if (value < inclusiveMinimum) { return inclusiveMinimum; }
if (value > inclusiveMaximum) { return inclusiveMaximum; }
return value;
}
我认为这在保持高效的同时更容易理解。
答案 4 :(得分:7)
我喜欢Guffa的答案,但我很惊讶没有人使用Min / Max发布解决方案。
public int LimitInclusive(int value, int min, int max)
{
return Math.Min(max, Math.Max(value, min));
}
答案 5 :(得分:3)
不,没有任何方法可以在框架中构建。我认为它已被遗漏,因为您已经拥有Min
和Max
,因此您可以使用它们来完成它。
如果您为自己编写自己的方法,那么编写它的方式并不重要。如果你使用if
语句或条件运算符?
,它仍然会编译成几乎相同的代码。
答案 6 :(得分:3)
为了限制值而不向用户提供任何反馈,即他们输入的值是错误的,一般来说,这可能不是一个好主意(恕我直言)。这可能会导致稍后的细微错误,这些错误很难调试,尤其是在运行时确定最小值/最大值时。
想一想。您的银行帐户中有100美元,而您希望将150美元转移给您的朋友。您是否希望您的银行系统抛出InsufficientFundsException
或与您的朋友讨论您转移了150美元,但他只收到100美元(假设由于您没有足够的资金,银行将转账金额限制为100)< / p>
话虽如此,您还应该查看代码合同。
public void MyFunction (Type input)
{
Contract.Requires(input > SomeReferenceValue);
Contract.Requires (input < SomeOtherReferencValue);
}
这将强制用户输入在范围内。
答案 7 :(得分:1)
我喜欢Clamp的名字。我会建议以下课程
public class MathHelper
{
public static int Clamp (int value,int min,int max)
{
// todo - implementation
}
public static float Clamp (float value,float min,float max)
{
// todo - implementation
}
)
或者如果你想使用泛型,那么
public class MathHelper
{
public static T Clamp<T> (T value, T min, T max) where T : IComparable
{
// todo - implementation
T output = value;
if (value.CompareTo(max) > 0)
{
return max;
}
if (value.CompareTo(min) < 0)
{
return min;
}
return output;
}
}