Я вижу ответ Марка и поднимаю его на это
:
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)
Эта операция называется 'Clamp' и обычно записывается так:
public static int Clamp( int value, int min, int max )
{
return (value < min) ? min : (value > max) ? max : value;
}
Более чистый метод, который будет работать не только с целыми числами (взяты из моей собственной библиотеки общего кода):
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;
}
Альтернативный способ написать вашу функцию LimitToRange
выглядит следующим образом.
public int LimitToRange(int value, int inclusiveMinimum, int inclusiveMaximum)
{
if (value < inclusiveMinimum) { return inclusiveMinimum; }
if (value > inclusiveMaximum) { return inclusiveMaximum; }
return value;
}
Я думаю, что это немного проще для понимания и в то же время эффективно.
Мне нравится ответ Гуффа, но я удивлен, что никто еще не опубликовал решение с использованием Min / Max.
public int LimitInclusive(int value, int min, int max)
{
return Math.Min(max, Math.Max(value, min));
}
Мне нравится название 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;
}
}
Зажимать значения, не давая пользователям никакой обратной связи о том, что введенное ими значение неверно, вообще говоря, может быть не очень хорошей идеей (IMHO). Впоследствии это может привести к тонким ошибкам, которые трудно отлаживать, особенно когда значения min/max определяются во время выполнения.
Подумайте вот о чем. У вас на банковском счету 100 долларов, и вы хотите перевести 150 долларов своему другу. Хотите ли вы, чтобы ваша банковская система выбросила InsufficientFundsException
или ввязалась в дискуссию с вашим другом о том, что вы перевели $150, а он получил только $100 (предполагая, что банк ограничил сумму перевода до 100, поскольку у вас не было достаточно средств)
Учитывая это, вам также следует обратить внимание на контракты кода.
public void MyFunction (Type input)
{
Contract.Requires(input > SomeReferenceValue);
Contract.Requires (input < SomeOtherReferencValue);
}
Это заставит пользователя вводить данные в пределах диапазона.
Нет, в фреймворке нет никакого метода для этого. Я предполагаю, что он был оставлен, потому что у вас уже есть Min
и Max
, так что вы можете решить эту задачу с их помощью.
Если вы напишите свой собственный метод для этого, то не имеет большого значения, как вы его напишете. Если вы используете операторы if
или условный оператор ?
, то все равно скомпилируется практически тот же код.