Как вынудить число быть в диапазоне в C#? [дубликат]

31
задан Arseni Mourzenko 9 February 2014 в 21:57
поделиться

8 ответов

Я вижу ответ Марка и поднимаю его на это:

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)

См: Методы расширения

27
ответ дан 27 November 2019 в 21:24
поделиться

Эта операция называется 'Clamp' и обычно записывается так:

public static int Clamp( int value, int min, int max )
{
    return (value < min) ? min : (value > max) ? max : value;
}
56
ответ дан 27 November 2019 в 21:24
поделиться

Более чистый метод, который будет работать не только с целыми числами (взяты из моей собственной библиотеки общего кода):

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;
}
27
ответ дан 27 November 2019 в 21:24
поделиться

Альтернативный способ написать вашу функцию LimitToRange выглядит следующим образом.

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

Я думаю, что это немного проще для понимания и в то же время эффективно.

7
ответ дан 27 November 2019 в 21:24
поделиться

Мне нравится ответ Гуффа, но я удивлен, что никто еще не опубликовал решение с использованием Min / Max.

public int LimitInclusive(int value, int min, int max)
{
    return Math.Min(max, Math.Max(value, min));
}
7
ответ дан 27 November 2019 в 21:24
поделиться

Мне нравится название 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;
     } 
}
1
ответ дан 27 November 2019 в 21:24
поделиться

Зажимать значения, не давая пользователям никакой обратной связи о том, что введенное ими значение неверно, вообще говоря, может быть не очень хорошей идеей (IMHO). Впоследствии это может привести к тонким ошибкам, которые трудно отлаживать, особенно когда значения min/max определяются во время выполнения.

Подумайте вот о чем. У вас на банковском счету 100 долларов, и вы хотите перевести 150 долларов своему другу. Хотите ли вы, чтобы ваша банковская система выбросила InsufficientFundsException или ввязалась в дискуссию с вашим другом о том, что вы перевели $150, а он получил только $100 (предполагая, что банк ограничил сумму перевода до 100, поскольку у вас не было достаточно средств)

Учитывая это, вам также следует обратить внимание на контракты кода.

public void MyFunction (Type input)
{
   Contract.Requires(input > SomeReferenceValue);
   Contract.Requires (input < SomeOtherReferencValue);

}

Это заставит пользователя вводить данные в пределах диапазона.

3
ответ дан 27 November 2019 в 21:24
поделиться

Нет, в фреймворке нет никакого метода для этого. Я предполагаю, что он был оставлен, потому что у вас уже есть Min и Max, так что вы можете решить эту задачу с их помощью.

Если вы напишите свой собственный метод для этого, то не имеет большого значения, как вы его напишете. Если вы используете операторы if или условный оператор ?, то все равно скомпилируется практически тот же код.

3
ответ дан 27 November 2019 в 21:24
поделиться