繁体   English   中英

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

[英]Is using decimal ranges in a switch impossible in C#?

我刚刚开始学习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;
            }

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

使用C#中的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;
}

你的进一步阅读部分,

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

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

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

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

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

玩得开心学习。

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

switch关键字可以正常使用小数。 这是<和>给你带来麻烦。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM