Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is using decimal ranges in a switch impossible in C#?

I'm just starting out learning C# and I've become stuck at something very basic.

For my first "app" I thought I'd go for something simple, so I decided for a BMI calculator.

The BMI is calculated into a decimal type which I'm now trying to use in a switch statement, but aparently decimal can't be used in a switch?

What would be the C# solution for this:

            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;
            }
like image 393
phobia Avatar asked May 30 '10 01:05

phobia


2 Answers

The switchstatement only supports integral types (enumerations are not listed but can be used with switch statements because they are backed by an integral type)(strings are also supported as pointed out by Changeling - see the comment for reference) and equality comparisons with constant values. Therefore you have to use some if statements.

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";
}

By the way your switch statement is a bit weired because you are switching from less than to greater than and using fall-through without breaks. I think one should use only one type of comparison to make the code easier to understand or reorder the checks and do not use fall-through.

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.
}
like image 81
Daniel Brückner Avatar answered Sep 28 '22 06:09

Daniel Brückner


That is not possible with switch statements in C#.
The reason why is because each case statement requires a constant expression after it.

Also each value is allowed only once and the type of the expression must match the type in your switch. In your case that is not the case because you wanted to have bool type case statements but a decimal in your switch.

Consider refactoring using a helper function instead:

//...
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;
}

Further reading:

Not only are range values not allowed but non constant expressions are also not allowed.

Here is an example of something that is not possible:

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

However this is possible:

bool b = true;
const bool y = false;
switch (b)
{
    case true:
        break;
    case y:
        break;
}
like image 30
Brian R. Bondy Avatar answered Sep 28 '22 08:09

Brian R. Bondy