Как изящно проверить, ли число в диапазоне?

Как я могу сделать это изящно с C# и.NET 3.5/4?

Например, число может быть между 1 и 100.

Я знаю простое, если был бы достаточен; но ключевое слово к этому вопросу является элегантностью. Это для моего игрушечного проекта не для производства.

Это подвергает сомнению, не был о скорости, а о красоте кода. Прекратите говорить об эффективности и таком; помните, что Вы проповедуете хору.

139
задан Peter Mortensen 19 May 2016 в 23:16
поделиться

10 ответов

Есть много вариантов:

int x = 30;
if (Enumerable.Range(1,100).Contains(x))
    //true

if (x >= 1 && x <= 100)
    //true

Кроме того, ознакомьтесь с этим сообщением SO , чтобы узнать о параметрах регулярных выражений.

126
ответ дан 23 November 2019 в 23:17
поделиться

В C, если эффективность использования времени имеет решающее значение, а целочисленные переполнения будут заворачиваться, можно сделать if ((unsigned)(value-min) <= (max-min)) ... . Если 'max' и 'min' являются независимыми переменными, дополнительное вычитание для (max-min) будет тратить время, но если это выражение может быть предварительно вычислено во время компиляции, или если оно может быть вычислено один раз во время выполнения для проверки многих чисел на одинаковый диапазон, вышеприведенное выражение может быть вычислено эффективно даже в случае, когда значение находится в диапазоне (если большая доля значений будет ниже допустимого диапазона, может быть быстрее использовать if ((value >= min) && (value <= max)) ... поскольку он завершится раньше, если значение меньше min).

Однако, прежде чем использовать подобную реализацию, проведите бенчмарк на своей целевой машине. На некоторых процессорах двухкомпонентное выражение может быть быстрее во всех случаях, поскольку два сравнения могут выполняться независимо, тогда как в методе вычитания и сравнения вычитание должно завершиться до выполнения сравнения.

1
ответ дан 23 November 2019 в 23:17
поделиться

Если это случайно, вам достаточно простого if . Если это происходит во многих местах, вы можете рассмотреть следующие два:

  • PostSharp . Украсьте методы атрибутами, которые «вставляют» код в метод после компиляции. Я не знаю точно, но могу представить, что это можно использовать для этого.

Примерно так:

[Between("parameter", 0, 100)]
public void Foo(int parameter)
{
}
  • Код контрактов . Преимущество заключается в том, что ограничения можно проверить во время компиляции путем статической проверки вашего кода и мест, где он используется.
7
ответ дан 23 November 2019 в 23:17
поделиться
if (value > 1 && value < 100)
{
    // do work
}
else
{
    // handle outside of range logic
}
5
ответ дан 23 November 2019 в 23:17
поделиться

Немного злоупотребляя методом расширения, мы можем получить следующее "элегантное" решение:

using System;

namespace Elegant {
    public class Range {
        public int Lower { get; set; }
        public int Upper { get; set; }
    }

    public static class Ext {
        public static Range To(this int lower, int upper) {
            return new Range { Lower = lower, Upper = upper };
        }

        public static bool In(this int n, Range r) {
            return n >= r.Lower && n <= r.Upper;
        }
    }

    class Program {
        static void Main() {
            int x = 55;
            if (x.In(1.To(100)))
                Console.WriteLine("it's in range! elegantly!");
        }
    }
}
18
ответ дан 23 November 2019 в 23:17
поделиться

Как говорили другие, используйте простое if.

Вам следует подумать об упорядочивании.

например,

1 <= x && x <= 100

легче читать, чем

x >= 1 && x <= 100
44
ответ дан 23 November 2019 в 23:17
поделиться

Вы имеете в виду?

if(number >= 1 && number <= 100)

или

bool TestRange (int numberToCheck, int bottom, int top)
{
  return (numberToCheck >= bottom && numberToCheck <= top);
}
88
ответ дан 23 November 2019 в 23:17
поделиться

Чтобы добавить сюда шума, вы можете создать метод расширения:

public static bool IsWithin(this int value, int minimum, int maximum)
{
    return value >= minimum && value <= maximum;
}

Который позволит вам сделать что-то вроде ...

int val = 15;

bool foo = val.IsWithin(5,20);

При этом это кажется глупым что делать, когда сама проверка - это всего одна строчка.

52
ответ дан 23 November 2019 в 23:17
поделиться

Новый поворот к старому любимому:

public bool IsWithinRange(int number, int topOfRange, int bottomOfRange, bool includeBoundaries) {
    if (includeBoundaries)
        return number <= topOfRange && number >= bottomOfRange;
    return number < topOfRange && number > bottomOfRange;
}
1
ответ дан 23 November 2019 в 23:17
поделиться

Использование выражения && для объединения двух сравнений - это просто самый элегантный способ сделать это. Если вы попытаетесь использовать причудливые методы расширения и тому подобное, вы столкнетесь с вопросом, следует ли включать верхнюю границу, нижнюю границу или и то, и другое. Как только вы начнете добавлять дополнительные переменные или изменять имена расширений, чтобы указать, что включено, ваш код становится длиннее и труднее читается (для подавляющего большинства программистов). Кроме того, такие инструменты, как Resharper, предупредят вас, если ваше сравнение не имеет смысла ( number> 100 && number <1 ), чего они не будут делать, если вы используете метод ('i.IsBetween (100 , 1) ').

Единственный другой комментарий, который я хотел бы сделать, это то, что если вы проверяете входные данные с намерением выбросить исключение, вам следует подумать об использовании контрактов кода:

Contract.Requires(number > 1 && number < 100)

Это более элегантно, чем if (... ) throw new Exception (...) , и вы даже можете получить предупреждения во время компиляции, если кто-то попытается вызвать ваш метод, не убедившись, что число сначала находится в границах.

5
ответ дан 23 November 2019 в 23:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: