在C#中无法在交换机中使用小数范围?

时间:2010-05-30 01:01:05

标签: c# decimal switch-statement

我刚刚开始学习C#而且我已经陷入了非常基本的困境。

对于我的第一个“应用程序”,我认为我会选择一些简单的东西,所以我决定使用BMI计算器。

BMI计算为十进制类型,我现在尝试在switch语句中使用,但是十字形小数不能在交换机中使用?

C#的解决方案是什么:

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

5 个答案:

答案 0 :(得分:14)

switch语句仅支持integral types(枚举未列出,但可以与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.
}

答案 1 :(得分:9)

C#中的switch语句无法做到这一点 原因是因为每个case语句都需要一个常量表达式。

此外,每个值只允许一次,表达式的类型必须与switch中的类型匹配。在您的情况下并非如此,因为您希望在case中使用bool类型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;
}

答案 2 :(得分:1)

您的进一步阅读部分,

开关只能在值或情况下操作,其中输入值是一个常量值,开关可以像索引一样查找并执行在案例或案例点或案例标签内定义的附加代码,无论是什么都可以可互换使用。

在第一个示例中将y更改为true,并且开关应在'b'上运行。

第二个例子有效,因为第二个例子是打开一个常量或'const'值。因此,您符合基本标准或交换机需要的内容。虽然这里的许多人肯定会告诉你不要这样编码。打开一个简单的常量值,并确保您的开关准确地满足您提供的变量可能具有的每个不同值。

尝试使用枚举使您的代码符合标准的.Net编码实践这条评论也符合确保您不想接受任何坏习惯,如果想要从事这个职业生涯???

请记住:您可以使用枚举并将其设置为使用小数值,因为十进制是一种值类型,因此这符合枚举所需的条件。由于枚举在.Net框架中定义为值类型,因此只能设置基于数字类型的值类型,以便在自定义代码类中创建枚举类型。只需使用上面使用的名称或某种类型附加每个值,例如超重等,并确保枚举中的每个条目都具有逻辑顺序。也就是说,十进制数值的上限具有明确的上升或下降的定义。设置枚举后,创建一个刚刚创建的枚举类型的变量,然后将此变量提供给您的开关。

玩得开心。

答案 3 :(得分:0)

您还可以使用某种存储截止值和描述的集合。 (我不是C#专家......也许Dictionary<decimal,string>?)通过它迭代找到最后一个小于你的bmi,并返回相应的标签。

答案 4 :(得分:0)

switch关键字可以正常使用小数。它是&lt;和&gt;那给你带来麻烦。