【问题标题】:C# Switches vs. VB Case StatementsC# 开关与 VB 案例语句
【发布时间】:2013-09-13 19:10:28
【问题描述】:

我最近从 VB 切换到 C#。我注意到的一件事是,在 C# 中,我在使用比较作为案例的一部分时遇到了问题。我不知道如何用语言来解释它,所以这里是我正在尝试做的一个例子。

在 VB 中,我的代码看起来像这样并且运行良好。

    Select Case ExamScore
        Case Is >= 90
            Grade = "A"
        Case Is >= 80
            Grade = "B"
        Case Is >= 70
            Grade = "C"
        Case Is >= 60
            Grade = "D"
        Case Else
            Grade = "F"
    End Select

另一方面,在 C# 中,Visual Studio 告诉我 ">=" 是一个无效的表达式。

    switch (examScore)
    {
        case >= 90: grade = "A"; break;
        case >= 80: grade = "B"; break;
        case >= 70: grade = "C"; break;
        case >= 60; grade = "D"; break;
        default: grade = "F"; break;
    }

我在这里做错了什么,还是在 C# 中根本不可能做到这一点?

非常感谢您!

【问题讨论】:

  • @Dominic - 虽然这是同一个问题,但我认为这些都不是正确的重复,因为这里的代码不能完全写成switch/case
  • jyparask 的答案是最直接的转换 - VB 的“选择案例”与 C# 的“开关”完全不同 - 它们仅等效于精确的整数或字符串匹配。

标签: c# vb.net switch-statement select-case


【解决方案1】:

此答案的顶部对于 7 之前的 C# 版本是正确的。请参阅下面的行以获取版本 7 的更新

这是不可能的。 C# switches 只能开启完全相等:

每个案例标签指定一个常量值。控制转移到 switch 部分,其 case 标签包含一个与 switch 表达式的值匹配的常量值,

你可以用一堆if/else 语句替换它,或者如果你愿意,你可以做一些看起来很紧凑,但有些人可能会皱眉的东西——一组条件运算符:

grade = examScore >= 90 ? "A" :
        examScore >= 80 ? "B" :
        examScore >= 70 ? "C" :
        examScore >= 60 ? "D" :
        "F";

在 C# 7 中,switch 一直是 significantly enhanced,现在可以在 cases 中应用更多条件,尽管它仍然不如 VB 版本“干净”。例如。你可以这样做:

switch (examScore)
{
    case int es when es >= 90: grade = "A"; break;
    case int es when es >= 80: grade = "B"; break;
    case int es when es >= 70: grade = "C"; break;
    case int es when es >= 60; grade = "D"; break;
    default: grade = "F"; break;
}

假设examScoreint,这有点滥用了新的“类型上的模式匹配”功能,以便能够在case 子句中表达一些内容,然后使用when 子句将任意条件应用于新引入的变量。

【讨论】:

    【解决方案2】:

    与 VB 不同,C# switch 语句类似于“等于”检查。所以你可能需要一个 if else 阶梯来完成这个。

    你可以试试这样的:

    private char Grade(int marks)
    {
        Dictionary<int, char> grades = new Dictionary<int, char> { { 60, 'A' }, { 50, 'B' } };
        foreach (var item in grades)
        {
            if (marks > item.Key)
                return item.Value;
        }
        return 'C';
    }
    

    【讨论】:

    • 虽然这有效,但 Dictionary 中的项目返回的顺序是未定义的。最好改用OrderedDictionary
    • 同意。您也可以尝试两个单独的列表。列表比 IMO 字典轻量级。
    【解决方案3】:

    这在 C# 中是不可能的。

    改用一堆ifs。

    【讨论】:

      【解决方案4】:

      您可以在不错的功能中拥有这一切:

      public string Grade(int examScore)
      {
          if(examScore>=90)
          {
              return "A";
          }
          if(examScore>=80)
          {
              return "B";
          }
          if(examScore>=70)
          {
              return "C";
          }
          if(examScore>=60)
          {
              return "D";
          }
          return "F";
      }
      

      【讨论】:

      • 我会选择 else 而不是 return 这里...原始问题中的示例代码不是 return
      • @MarcGravell 我宁愿把它放在一个函数中。
      • 需要稍微调整一下;例如,永远不会返回“F”级。
      • 只是为了返回所有if statements中的值,为什么你需要一个局部变量呢?
      • @Bathsheba 我返回的是“F”,但现在可能更明显了。
      【解决方案5】:

      如果你真的想要一个 switch 语句,你可以使用整数除法

              int i = 69;
              switch (Math.Min(9, i / 10))
              {
                  case 9: Grade = "A"; break;
                  case 6: Grade = "B"; break;
              }
      

      【讨论】:

      • 嘿 - 你甚至不需要混淆器!我认为,如果您编写的代码很难立即理解,那么您最好以更直接的方式完成一些非常尴尬的事情。
      • @DaveDoknjas - 虽然仍在使用 switch 语句,但这是您能做的最接近的事情。我认为它没有那么模糊,任何熟悉简单数学的人都会理解它
      • 如果透明清晰的逻辑可用,那么应该使用它。如果有人必须维护此代码,则出错的可能性会更高。
      • @DaveDoknjas 我不确定你想在这里证明什么。我在大学的第一年为了学习不同的 C# 语法而不得不做的这个确切的问题,我已经对这个问题提出了其他答案,所以它不像我曾经使用过这段代码。 "如果你真的想要一个 switch 语句.."
      • 我唯一的观点是“聪明”的解决方案通常是脆弱的,因此是坏主意。最好有难以破解的“可靠”解决方案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-20
      • 2015-06-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-09
      相关资源
      最近更新 更多