Подтвердить что ты не робот

Является ли использование десятичных диапазонов в переключателе невозможным в С#?

Я только начинаю изучать С#, и я застрял в чем-то очень базовом.

Для моего первого "приложения" я подумал, что пойду на что-то простое, поэтому решил выбрать калькулятор BMI.

ИМТ рассчитывается в десятичный тип, который я теперь пытаюсь использовать в инструкции switch, но apalently decimal нельзя использовать в коммутаторе?

Каким будет решение С# для этого:

            decimal bmi = calculate_bmi(h, w);

            switch (bmi) {
                case < 18.5: 
                    bmi_description = "underweight.";
                    break;
                case > 25:
                    bmi_description = "overweight";
                case > 30:
                    bmi_description = "very overweight";
                case > 40:
                    bmi_description = "extreme overweight";
                    break;
            }
4b9b3361

Ответ 1

Оператор switch поддерживает только интегральные типы (перечисления не перечислены, но могут использоваться с операторами switch, потому что они поддерживаются интегральный тип) (строки также поддерживаются, как указано Changeling - см. комментарий для справки) и сравнения равенств с постоянными значениями. Поэтому вам нужно использовать несколько операторов if.

if (bmi < 18.5M)
{
    bmi_description = "underweight.";
}
else if (bmi <= 25)
{
    // You missed the 'normal' case in your example.
}
else if (bmi <= 30)
{
    bmi_description = "overweight";
}
else if (bmi <= 40)
{
    bmi_description = "very overweight";
}
else
{
    bmi_description = "extreme overweight";
}

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

if (bmi < 18.5M)
{
    bmi_description = "underweight.";
}
else if (bmi > 40)
{
    bmi_description = "extreme overweight";
}
else if (bmi > 30)
{
    bmi_description = "very overweight";
}
else if (bmi > 25)
{
    bmi_description = "overweight";
}
else
{
    // You missed the 'normal' case in your example.
}

Ответ 2

Это невозможно с помощью switch в С#.
Причина в том, что каждый оператор case требует от него постоянного выражения.

Также каждое значение разрешено только один раз, а тип выражения должен соответствовать типу в switch. В вашем случае это не так, потому что вы хотели иметь инструкции типа bool case, но десятичные числа в switch.

Рассмотрим рефакторинг вместо вспомогательной функции:

//...
decimal bmi = calculate_bmi(h, w);
string bmi_description = get_description_for_bmi(bmi);
//...

string get_description_for_bmi(decimal bmi)
{
    string desc;
    if(bmi < 18.5m)
      desc = "underweight";
    else if(bmi <= 25)
      desc = "average";//You forgot this one btw
    else if(bmi <= 30)
      desc = "overweight";
    else if(bmi <= 40)
      desc = "very overweight";     
    else
      desc = "extreme overweight";

    return desc;
}

Дальнейшее чтение:

Значения диапазона не допускаются, но не константные выражения также не допускаются.

Вот пример чего-то, что невозможно:

bool b = true;
bool y = false;
switch (b)
{
    case true:
        break;
    case y:
        break;
}

Однако это возможно:

bool b = true;
const bool y = false;
switch (b)
{
    case true:
        break;
    case y:
        break;
}

Ответ 3

Ваш дальнейший раздел для чтения,

Коммутаторы

могут управляться только по значениям или случаям, при которых входное значение является постоянным значением, которое коммутатор может выглядеть как индекс и выполнять прикрепленный код, определенный внутри фрейма case или case или case, независимо от того, что все может быть используется взаимозаменяемо.

В первом примере измените y на true, и переключатель должен работать на 'b'.

Второй пример работает, потому что второй случай включает значение константы или 'const'. Поэтому вы отвечаете основным критериям или требованиям коммутатора. Хотя многие из вас здесь определенно скажут вам не кодировать это. Включите простое постоянное значение и убедитесь, что ваш коммутатор точно подходит для каждого из разных значений, которые может быть предоставлена ​​вашей переменной.

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

ЗАПОМНИТЕ: вы можете использовать перечисление и настроить его для использования десятичных значений, поскольку decimal - это тип значения, так что это соответствует критериям того, что требует перечисление. Поскольку перечисление определено в .Net-структуре как тип значения, так что только значения типов, таких как числовые типы, могут быть настроены для создания типа перечисления в пользовательских классах кода yuor. Просто прикрепите каждое значение с именем или каким-то видом, как вы использовали выше, например, над весом и т.д. И убедитесь, что каждая запись в перечислении имеет логическое упорядочение. т.е. записи в терминах десятичных значений имеют четкое определение перехода вверх или вниз. После того, как ваше перечисление настроено, создайте переменную типа только что созданного перечисления, а затем поставьте эту переменную на свой коммутатор.

Получайте удовольствие от обучения.

Ответ 4

Вы также можете использовать какую-то коллекцию, в которой хранятся значения отсечки и описания. (Я не эксперт на С#... может быть, Dictionary<decimal,string>?) Проведите через него, чтобы найти последний, который меньше вашего bmi, и верните его соответствующую метку.

Ответ 5

Ключевое слово switch отлично работает с десятичными знаками. Это < и > , которые дают вам неприятности.